blob: b8fb9b82930e36facade0087b40405cb9f0422dc [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
Rich Lanee3a59722013-01-11 12:50:25 -08001875 self.actions = []
Rich Lane629393f2013-01-10 15:37:33 -08001876 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 Lanee3a59722013-01-11 12:50:25 -08001882 self.actions = action_list(self.actions)
Rich Lane629393f2013-01-10 15:37:33 -08001883
1884
1885 def pack(self):
1886 """
1887 Pack object into string
1888
1889 @return The packed string which can go on the wire
1890
1891 """
1892 self.header.length = len(self)
1893 packed = self.header.pack()
1894
1895 self.actions_len = len(self.actions)
1896 packed += ofp_packet_out.pack(self)
1897 packed += self.actions.pack()
1898 packed += self.data
1899 return packed
1900
1901 def unpack(self, binary_string):
1902 """
1903 Unpack object from a binary string
1904
1905 @param binary_string The wire protocol byte string holding the object
1906 represented as an array of bytes.
1907 @return The remainder of binary_string that was not parsed.
1908
1909 """
1910 binary_string = self.header.unpack(binary_string)
1911
1912 binary_string = ofp_packet_out.unpack(self, binary_string)
1913 binary_string = self.actions.unpack(binary_string, bytes=self.actions_len)
1914 self.data = binary_string
1915 binary_string = ''
1916 return binary_string
1917
1918 def __len__(self):
1919 """
1920 Return the length of this object once packed into a string
1921
1922 @return An integer representing the number bytes in the packed
1923 string.
1924
1925 """
1926 length = OFP_HEADER_BYTES
1927
1928 length += ofp_packet_out.__len__(self)
1929 length += len(self.actions)
1930 length += len(self.data)
1931 return length
1932
1933 def show(self, prefix=''):
1934 """
1935 Generate a string (with multiple lines) describing the contents
1936 of the object in a readable manner
1937
1938 @param prefix Pre-pended at the beginning of each line.
1939
1940 """
1941
1942 outstr = prefix + 'packet_out (OFPT_PACKET_OUT)\n'
1943 prefix += ' '
1944 outstr += prefix + 'ofp header\n'
1945 outstr += self.header.show(prefix + ' ')
1946 outstr += ofp_packet_out.show(self, prefix)
1947 outstr += prefix + "List actions\n"
1948 outstr += self.actions.show(prefix + ' ')
1949 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1950 ##@todo Fix this circular reference
1951 # if len(self.data) > 0:
1952 # obj = of_message_parse(self.data)
1953 # if obj != None:
1954 # outstr += obj.show(prefix)
1955 # else:
1956 # outstr += prefix + "Unable to parse data\n"
1957 return outstr
1958
1959 def __eq__(self, other):
1960 """
1961 Return True if self and other hold the same data
1962
1963 @param other Other object in comparison
1964
1965 """
1966 if type(self) != type(other): return False
1967 if not self.header.__eq__(other.header): return False
1968
1969 if not ofp_packet_out.__eq__(self, other): return False
1970 if self.data != other.data: return False
1971 if self.actions != other.actions: return False
1972 return True
1973
1974 def __ne__(self, other):
1975 """
1976 Return True if self and other do not hold the same data
1977
1978 @param other Other object in comparison
1979
1980 """
1981 return not self.__eq__(other)
1982
1983
1984class port_mod(ofp_port_mod):
1985 """
1986 Wrapper class for port_mod
1987
1988 OpenFlow message header: length, version, xid, type
1989 @arg length: The total length of the message
1990 @arg version: The OpenFlow version (3)
1991 @arg xid: The transaction ID
1992 @arg type: The message type (OFPT_PORT_MOD=16)
1993
1994 Data members inherited from ofp_port_mod:
1995 @arg port_no
1996 @arg hw_addr
1997 @arg config
1998 @arg mask
1999 @arg advertise
2000
2001 """
2002
Rich Lane5de2d942013-01-11 11:49:36 -08002003 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002004 ofp_port_mod.__init__(self)
2005 self.header = ofp_header()
2006 self.header.type = OFPT_PORT_MOD
Rich Lane5de2d942013-01-11 11:49:36 -08002007 for (k, v) in kwargs.items():
2008 if hasattr(self, k):
2009 setattr(self, k, v)
2010 else:
2011 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002012
2013
2014 def pack(self):
2015 """
2016 Pack object into string
2017
2018 @return The packed string which can go on the wire
2019
2020 """
2021 self.header.length = len(self)
2022 packed = self.header.pack()
2023
2024 packed += ofp_port_mod.pack(self)
2025 return packed
2026
2027 def unpack(self, binary_string):
2028 """
2029 Unpack object from a binary string
2030
2031 @param binary_string The wire protocol byte string holding the object
2032 represented as an array of bytes.
2033 @return The remainder of binary_string that was not parsed.
2034
2035 """
2036 binary_string = self.header.unpack(binary_string)
2037
2038 binary_string = ofp_port_mod.unpack(self, binary_string)
2039 # Fixme: If no self.data, add check for data remaining
2040 return binary_string
2041
2042 def __len__(self):
2043 """
2044 Return the length of this object once packed into a string
2045
2046 @return An integer representing the number bytes in the packed
2047 string.
2048
2049 """
2050 length = OFP_HEADER_BYTES
2051
2052 length += ofp_port_mod.__len__(self)
2053 return length
2054
2055 def show(self, prefix=''):
2056 """
2057 Generate a string (with multiple lines) describing the contents
2058 of the object in a readable manner
2059
2060 @param prefix Pre-pended at the beginning of each line.
2061
2062 """
2063
2064 outstr = prefix + 'port_mod (OFPT_PORT_MOD)\n'
2065 prefix += ' '
2066 outstr += prefix + 'ofp header\n'
2067 outstr += self.header.show(prefix + ' ')
2068 outstr += ofp_port_mod.show(self, prefix)
2069 return outstr
2070
2071 def __eq__(self, other):
2072 """
2073 Return True if self and other hold the same data
2074
2075 @param other Other object in comparison
2076
2077 """
2078 if type(self) != type(other): return False
2079 if not self.header.__eq__(other.header): return False
2080
2081 if not ofp_port_mod.__eq__(self, other): return False
2082 return True
2083
2084 def __ne__(self, other):
2085 """
2086 Return True if self and other do not hold the same data
2087
2088 @param other Other object in comparison
2089
2090 """
2091 return not self.__eq__(other)
2092
2093
2094class port_status(ofp_port_status):
2095 """
2096 Wrapper class for port_status
2097
2098 OpenFlow message header: length, version, xid, type
2099 @arg length: The total length of the message
2100 @arg version: The OpenFlow version (3)
2101 @arg xid: The transaction ID
2102 @arg type: The message type (OFPT_PORT_STATUS=12)
2103
2104 Data members inherited from ofp_port_status:
2105 @arg reason
2106 @arg desc
2107
2108 """
2109
Rich Lane5de2d942013-01-11 11:49:36 -08002110 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002111 ofp_port_status.__init__(self)
2112 self.header = ofp_header()
2113 self.header.type = OFPT_PORT_STATUS
Rich Lane5de2d942013-01-11 11:49:36 -08002114 for (k, v) in kwargs.items():
2115 if hasattr(self, k):
2116 setattr(self, k, v)
2117 else:
2118 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002119
2120
2121 def pack(self):
2122 """
2123 Pack object into string
2124
2125 @return The packed string which can go on the wire
2126
2127 """
2128 self.header.length = len(self)
2129 packed = self.header.pack()
2130
2131 packed += ofp_port_status.pack(self)
2132 return packed
2133
2134 def unpack(self, binary_string):
2135 """
2136 Unpack object from a binary string
2137
2138 @param binary_string The wire protocol byte string holding the object
2139 represented as an array of bytes.
2140 @return The remainder of binary_string that was not parsed.
2141
2142 """
2143 binary_string = self.header.unpack(binary_string)
2144
2145 binary_string = ofp_port_status.unpack(self, binary_string)
2146 # Fixme: If no self.data, add check for data remaining
2147 return binary_string
2148
2149 def __len__(self):
2150 """
2151 Return the length of this object once packed into a string
2152
2153 @return An integer representing the number bytes in the packed
2154 string.
2155
2156 """
2157 length = OFP_HEADER_BYTES
2158
2159 length += ofp_port_status.__len__(self)
2160 return length
2161
2162 def show(self, prefix=''):
2163 """
2164 Generate a string (with multiple lines) describing the contents
2165 of the object in a readable manner
2166
2167 @param prefix Pre-pended at the beginning of each line.
2168
2169 """
2170
2171 outstr = prefix + 'port_status (OFPT_PORT_STATUS)\n'
2172 prefix += ' '
2173 outstr += prefix + 'ofp header\n'
2174 outstr += self.header.show(prefix + ' ')
2175 outstr += ofp_port_status.show(self, prefix)
2176 return outstr
2177
2178 def __eq__(self, other):
2179 """
2180 Return True if self and other hold the same data
2181
2182 @param other Other object in comparison
2183
2184 """
2185 if type(self) != type(other): return False
2186 if not self.header.__eq__(other.header): return False
2187
2188 if not ofp_port_status.__eq__(self, other): return False
2189 return True
2190
2191 def __ne__(self, other):
2192 """
2193 Return True if self and other do not hold the same data
2194
2195 @param other Other object in comparison
2196
2197 """
2198 return not self.__eq__(other)
2199
2200
2201class queue_get_config_reply(ofp_queue_get_config_reply):
2202 """
2203 Wrapper class for queue_get_config_reply
2204
2205 OpenFlow message header: length, version, xid, type
2206 @arg length: The total length of the message
2207 @arg version: The OpenFlow version (3)
2208 @arg xid: The transaction ID
2209 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REPLY=23)
2210
2211 Data members inherited from ofp_queue_get_config_reply:
2212 @arg port
2213 @arg queues: Variable length array of TBD
2214
2215 """
2216
Rich Lane5de2d942013-01-11 11:49:36 -08002217 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002218 ofp_queue_get_config_reply.__init__(self)
2219 self.header = ofp_header()
2220 self.header.type = OFPT_QUEUE_GET_CONFIG_REPLY
2221 self.queues = []
Rich Lane5de2d942013-01-11 11:49:36 -08002222 for (k, v) in kwargs.items():
2223 if hasattr(self, k):
2224 setattr(self, k, v)
2225 else:
2226 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002227
2228
2229 def pack(self):
2230 """
2231 Pack object into string
2232
2233 @return The packed string which can go on the wire
2234
2235 """
2236 self.header.length = len(self)
2237 packed = self.header.pack()
2238
2239 packed += ofp_queue_get_config_reply.pack(self)
2240 for obj in self.queues:
2241 packed += obj.pack()
2242 return packed
2243
2244 def unpack(self, binary_string):
2245 """
2246 Unpack object from a binary string
2247
2248 @param binary_string The wire protocol byte string holding the object
2249 represented as an array of bytes.
2250 @return The remainder of binary_string that was not parsed.
2251
2252 """
2253 binary_string = self.header.unpack(binary_string)
2254
2255 binary_string = ofp_queue_get_config_reply.unpack(self, binary_string)
2256 for obj in self.queues:
2257 binary_string = obj.unpack(binary_string)
2258 # Fixme: If no self.data, add check for data remaining
2259 return binary_string
2260
2261 def __len__(self):
2262 """
2263 Return the length of this object once packed into a string
2264
2265 @return An integer representing the number bytes in the packed
2266 string.
2267
2268 """
2269 length = OFP_HEADER_BYTES
2270
2271 length += ofp_queue_get_config_reply.__len__(self)
2272 for obj in self.queues:
2273 length += len(obj)
2274 return length
2275
2276 def show(self, prefix=''):
2277 """
2278 Generate a string (with multiple lines) describing the contents
2279 of the object in a readable manner
2280
2281 @param prefix Pre-pended at the beginning of each line.
2282
2283 """
2284
2285 outstr = prefix + 'queue_get_config_reply (OFPT_QUEUE_GET_CONFIG_REPLY)\n'
2286 prefix += ' '
2287 outstr += prefix + 'ofp header\n'
2288 outstr += self.header.show(prefix + ' ')
2289 outstr += ofp_queue_get_config_reply.show(self, prefix)
2290 outstr += prefix + "Array queues\n"
2291 for obj in self.queues:
2292 outstr += obj.show(prefix + ' ')
2293 return outstr
2294
2295 def __eq__(self, other):
2296 """
2297 Return True if self and other hold the same data
2298
2299 @param other Other object in comparison
2300
2301 """
2302 if type(self) != type(other): return False
2303 if not self.header.__eq__(other.header): return False
2304
2305 if not ofp_queue_get_config_reply.__eq__(self, other): return False
2306 if self.queues != other.queues: return False
2307 return True
2308
2309 def __ne__(self, other):
2310 """
2311 Return True if self and other do not hold the same data
2312
2313 @param other Other object in comparison
2314
2315 """
2316 return not self.__eq__(other)
2317
2318
2319class queue_get_config_request(ofp_queue_get_config_request):
2320 """
2321 Wrapper class for queue_get_config_request
2322
2323 OpenFlow message header: length, version, xid, type
2324 @arg length: The total length of the message
2325 @arg version: The OpenFlow version (3)
2326 @arg xid: The transaction ID
2327 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REQUEST=22)
2328
2329 Data members inherited from ofp_queue_get_config_request:
2330 @arg port
2331
2332 """
2333
Rich Lane5de2d942013-01-11 11:49:36 -08002334 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002335 ofp_queue_get_config_request.__init__(self)
2336 self.header = ofp_header()
2337 self.header.type = OFPT_QUEUE_GET_CONFIG_REQUEST
Rich Lane5de2d942013-01-11 11:49:36 -08002338 for (k, v) in kwargs.items():
2339 if hasattr(self, k):
2340 setattr(self, k, v)
2341 else:
2342 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002343
2344
2345 def pack(self):
2346 """
2347 Pack object into string
2348
2349 @return The packed string which can go on the wire
2350
2351 """
2352 self.header.length = len(self)
2353 packed = self.header.pack()
2354
2355 packed += ofp_queue_get_config_request.pack(self)
2356 return packed
2357
2358 def unpack(self, binary_string):
2359 """
2360 Unpack object from a binary string
2361
2362 @param binary_string The wire protocol byte string holding the object
2363 represented as an array of bytes.
2364 @return The remainder of binary_string that was not parsed.
2365
2366 """
2367 binary_string = self.header.unpack(binary_string)
2368
2369 binary_string = ofp_queue_get_config_request.unpack(self, binary_string)
2370 # Fixme: If no self.data, add check for data remaining
2371 return binary_string
2372
2373 def __len__(self):
2374 """
2375 Return the length of this object once packed into a string
2376
2377 @return An integer representing the number bytes in the packed
2378 string.
2379
2380 """
2381 length = OFP_HEADER_BYTES
2382
2383 length += ofp_queue_get_config_request.__len__(self)
2384 return length
2385
2386 def show(self, prefix=''):
2387 """
2388 Generate a string (with multiple lines) describing the contents
2389 of the object in a readable manner
2390
2391 @param prefix Pre-pended at the beginning of each line.
2392
2393 """
2394
2395 outstr = prefix + 'queue_get_config_request (OFPT_QUEUE_GET_CONFIG_REQUEST)\n'
2396 prefix += ' '
2397 outstr += prefix + 'ofp header\n'
2398 outstr += self.header.show(prefix + ' ')
2399 outstr += ofp_queue_get_config_request.show(self, prefix)
2400 return outstr
2401
2402 def __eq__(self, other):
2403 """
2404 Return True if self and other hold the same data
2405
2406 @param other Other object in comparison
2407
2408 """
2409 if type(self) != type(other): return False
2410 if not self.header.__eq__(other.header): return False
2411
2412 if not ofp_queue_get_config_request.__eq__(self, other): return False
2413 return True
2414
2415 def __ne__(self, other):
2416 """
2417 Return True if self and other do not hold the same data
2418
2419 @param other Other object in comparison
2420
2421 """
2422 return not self.__eq__(other)
2423
2424
2425class set_config(ofp_switch_config):
2426 """
2427 Wrapper class for set_config
2428
2429 OpenFlow message header: length, version, xid, type
2430 @arg length: The total length of the message
2431 @arg version: The OpenFlow version (3)
2432 @arg xid: The transaction ID
2433 @arg type: The message type (OFPT_SET_CONFIG=9)
2434
2435 Data members inherited from ofp_switch_config:
2436 @arg flags
2437 @arg miss_send_len
2438
2439 """
2440
Rich Lane5de2d942013-01-11 11:49:36 -08002441 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002442 ofp_switch_config.__init__(self)
2443 self.header = ofp_header()
2444 self.header.type = OFPT_SET_CONFIG
Rich Lane5de2d942013-01-11 11:49:36 -08002445 for (k, v) in kwargs.items():
2446 if hasattr(self, k):
2447 setattr(self, k, v)
2448 else:
2449 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002450
2451
2452 def pack(self):
2453 """
2454 Pack object into string
2455
2456 @return The packed string which can go on the wire
2457
2458 """
2459 self.header.length = len(self)
2460 packed = self.header.pack()
2461
2462 packed += ofp_switch_config.pack(self)
2463 return packed
2464
2465 def unpack(self, binary_string):
2466 """
2467 Unpack object from a binary string
2468
2469 @param binary_string The wire protocol byte string holding the object
2470 represented as an array of bytes.
2471 @return The remainder of binary_string that was not parsed.
2472
2473 """
2474 binary_string = self.header.unpack(binary_string)
2475
2476 binary_string = ofp_switch_config.unpack(self, binary_string)
2477 # Fixme: If no self.data, add check for data remaining
2478 return binary_string
2479
2480 def __len__(self):
2481 """
2482 Return the length of this object once packed into a string
2483
2484 @return An integer representing the number bytes in the packed
2485 string.
2486
2487 """
2488 length = OFP_HEADER_BYTES
2489
2490 length += ofp_switch_config.__len__(self)
2491 return length
2492
2493 def show(self, prefix=''):
2494 """
2495 Generate a string (with multiple lines) describing the contents
2496 of the object in a readable manner
2497
2498 @param prefix Pre-pended at the beginning of each line.
2499
2500 """
2501
2502 outstr = prefix + 'set_config (OFPT_SET_CONFIG)\n'
2503 prefix += ' '
2504 outstr += prefix + 'ofp header\n'
2505 outstr += self.header.show(prefix + ' ')
2506 outstr += ofp_switch_config.show(self, prefix)
2507 return outstr
2508
2509 def __eq__(self, other):
2510 """
2511 Return True if self and other hold the same data
2512
2513 @param other Other object in comparison
2514
2515 """
2516 if type(self) != type(other): return False
2517 if not self.header.__eq__(other.header): return False
2518
2519 if not ofp_switch_config.__eq__(self, other): return False
2520 return True
2521
2522 def __ne__(self, other):
2523 """
2524 Return True if self and other do not hold the same data
2525
2526 @param other Other object in comparison
2527
2528 """
2529 return not self.__eq__(other)
2530
2531
2532class stats_reply(ofp_stats_reply):
2533 """
2534 Wrapper class for stats_reply
2535
2536 OpenFlow message header: length, version, xid, type
2537 @arg length: The total length of the message
2538 @arg version: The OpenFlow version (3)
2539 @arg xid: The transaction ID
2540 @arg type: The message type (OFPT_STATS_REPLY=19)
2541
2542 Data members inherited from ofp_stats_reply:
2543 @arg type
2544 @arg flags
2545
2546 """
2547
Rich Lane5de2d942013-01-11 11:49:36 -08002548 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002549 ofp_stats_reply.__init__(self)
2550 self.header = ofp_header()
2551 self.header.type = OFPT_STATS_REPLY
Rich Lane5de2d942013-01-11 11:49:36 -08002552 for (k, v) in kwargs.items():
2553 if hasattr(self, k):
2554 setattr(self, k, v)
2555 else:
2556 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002557
2558
2559 def pack(self):
2560 """
2561 Pack object into string
2562
2563 @return The packed string which can go on the wire
2564
2565 """
2566 self.header.length = len(self)
2567 packed = self.header.pack()
2568
2569 packed += ofp_stats_reply.pack(self)
2570 return packed
2571
2572 def unpack(self, binary_string):
2573 """
2574 Unpack object from a binary string
2575
2576 @param binary_string The wire protocol byte string holding the object
2577 represented as an array of bytes.
2578 @return The remainder of binary_string that was not parsed.
2579
2580 """
2581 binary_string = self.header.unpack(binary_string)
2582
2583 binary_string = ofp_stats_reply.unpack(self, binary_string)
2584 # Fixme: If no self.data, add check for data remaining
2585 return binary_string
2586
2587 def __len__(self):
2588 """
2589 Return the length of this object once packed into a string
2590
2591 @return An integer representing the number bytes in the packed
2592 string.
2593
2594 """
2595 length = OFP_HEADER_BYTES
2596
2597 length += ofp_stats_reply.__len__(self)
2598 return length
2599
2600 def show(self, prefix=''):
2601 """
2602 Generate a string (with multiple lines) describing the contents
2603 of the object in a readable manner
2604
2605 @param prefix Pre-pended at the beginning of each line.
2606
2607 """
2608
2609 outstr = prefix + 'stats_reply (OFPT_STATS_REPLY)\n'
2610 prefix += ' '
2611 outstr += prefix + 'ofp header\n'
2612 outstr += self.header.show(prefix + ' ')
2613 outstr += ofp_stats_reply.show(self, prefix)
2614 return outstr
2615
2616 def __eq__(self, other):
2617 """
2618 Return True if self and other hold the same data
2619
2620 @param other Other object in comparison
2621
2622 """
2623 if type(self) != type(other): return False
2624 if not self.header.__eq__(other.header): return False
2625
2626 if not ofp_stats_reply.__eq__(self, other): return False
2627 return True
2628
2629 def __ne__(self, other):
2630 """
2631 Return True if self and other do not hold the same data
2632
2633 @param other Other object in comparison
2634
2635 """
2636 return not self.__eq__(other)
2637
2638
2639class stats_request(ofp_stats_request):
2640 """
2641 Wrapper class for stats_request
2642
2643 OpenFlow message header: length, version, xid, type
2644 @arg length: The total length of the message
2645 @arg version: The OpenFlow version (3)
2646 @arg xid: The transaction ID
2647 @arg type: The message type (OFPT_STATS_REQUEST=18)
2648
2649 Data members inherited from ofp_stats_request:
2650 @arg type
2651 @arg flags
2652
2653 """
2654
Rich Lane5de2d942013-01-11 11:49:36 -08002655 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002656 ofp_stats_request.__init__(self)
2657 self.header = ofp_header()
2658 self.header.type = OFPT_STATS_REQUEST
Rich Lane5de2d942013-01-11 11:49:36 -08002659 for (k, v) in kwargs.items():
2660 if hasattr(self, k):
2661 setattr(self, k, v)
2662 else:
2663 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002664
2665
2666 def pack(self):
2667 """
2668 Pack object into string
2669
2670 @return The packed string which can go on the wire
2671
2672 """
2673 self.header.length = len(self)
2674 packed = self.header.pack()
2675
2676 packed += ofp_stats_request.pack(self)
2677 return packed
2678
2679 def unpack(self, binary_string):
2680 """
2681 Unpack object from a binary string
2682
2683 @param binary_string The wire protocol byte string holding the object
2684 represented as an array of bytes.
2685 @return The remainder of binary_string that was not parsed.
2686
2687 """
2688 binary_string = self.header.unpack(binary_string)
2689
2690 binary_string = ofp_stats_request.unpack(self, binary_string)
2691 # Fixme: If no self.data, add check for data remaining
2692 return binary_string
2693
2694 def __len__(self):
2695 """
2696 Return the length of this object once packed into a string
2697
2698 @return An integer representing the number bytes in the packed
2699 string.
2700
2701 """
2702 length = OFP_HEADER_BYTES
2703
2704 length += ofp_stats_request.__len__(self)
2705 return length
2706
2707 def show(self, prefix=''):
2708 """
2709 Generate a string (with multiple lines) describing the contents
2710 of the object in a readable manner
2711
2712 @param prefix Pre-pended at the beginning of each line.
2713
2714 """
2715
2716 outstr = prefix + 'stats_request (OFPT_STATS_REQUEST)\n'
2717 prefix += ' '
2718 outstr += prefix + 'ofp header\n'
2719 outstr += self.header.show(prefix + ' ')
2720 outstr += ofp_stats_request.show(self, prefix)
2721 return outstr
2722
2723 def __eq__(self, other):
2724 """
2725 Return True if self and other hold the same data
2726
2727 @param other Other object in comparison
2728
2729 """
2730 if type(self) != type(other): return False
2731 if not self.header.__eq__(other.header): return False
2732
2733 if not ofp_stats_request.__eq__(self, other): return False
2734 return True
2735
2736 def __ne__(self, other):
2737 """
2738 Return True if self and other do not hold the same data
2739
2740 @param other Other object in comparison
2741
2742 """
2743 return not self.__eq__(other)
2744
2745
2746class table_mod(ofp_table_mod):
2747 """
2748 Wrapper class for table_mod
2749
2750 OpenFlow message header: length, version, xid, type
2751 @arg length: The total length of the message
2752 @arg version: The OpenFlow version (3)
2753 @arg xid: The transaction ID
2754 @arg type: The message type (OFPT_TABLE_MOD=17)
2755
2756 Data members inherited from ofp_table_mod:
2757 @arg table_id
2758 @arg config
2759
2760 """
2761
Rich Lane5de2d942013-01-11 11:49:36 -08002762 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002763 ofp_table_mod.__init__(self)
2764 self.header = ofp_header()
2765 self.header.type = OFPT_TABLE_MOD
Rich Lane5de2d942013-01-11 11:49:36 -08002766 for (k, v) in kwargs.items():
2767 if hasattr(self, k):
2768 setattr(self, k, v)
2769 else:
2770 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002771
2772
2773 def pack(self):
2774 """
2775 Pack object into string
2776
2777 @return The packed string which can go on the wire
2778
2779 """
2780 self.header.length = len(self)
2781 packed = self.header.pack()
2782
2783 packed += ofp_table_mod.pack(self)
2784 return packed
2785
2786 def unpack(self, binary_string):
2787 """
2788 Unpack object from a binary string
2789
2790 @param binary_string The wire protocol byte string holding the object
2791 represented as an array of bytes.
2792 @return The remainder of binary_string that was not parsed.
2793
2794 """
2795 binary_string = self.header.unpack(binary_string)
2796
2797 binary_string = ofp_table_mod.unpack(self, binary_string)
2798 # Fixme: If no self.data, add check for data remaining
2799 return binary_string
2800
2801 def __len__(self):
2802 """
2803 Return the length of this object once packed into a string
2804
2805 @return An integer representing the number bytes in the packed
2806 string.
2807
2808 """
2809 length = OFP_HEADER_BYTES
2810
2811 length += ofp_table_mod.__len__(self)
2812 return length
2813
2814 def show(self, prefix=''):
2815 """
2816 Generate a string (with multiple lines) describing the contents
2817 of the object in a readable manner
2818
2819 @param prefix Pre-pended at the beginning of each line.
2820
2821 """
2822
2823 outstr = prefix + 'table_mod (OFPT_TABLE_MOD)\n'
2824 prefix += ' '
2825 outstr += prefix + 'ofp header\n'
2826 outstr += self.header.show(prefix + ' ')
2827 outstr += ofp_table_mod.show(self, prefix)
2828 return outstr
2829
2830 def __eq__(self, other):
2831 """
2832 Return True if self and other hold the same data
2833
2834 @param other Other object in comparison
2835
2836 """
2837 if type(self) != type(other): return False
2838 if not self.header.__eq__(other.header): return False
2839
2840 if not ofp_table_mod.__eq__(self, other): return False
2841 return True
2842
2843 def __ne__(self, other):
2844 """
2845 Return True if self and other do not hold the same data
2846
2847 @param other Other object in comparison
2848
2849 """
2850 return not self.__eq__(other)
2851
2852
2853
2854################################################################
2855#
2856# Stats request and reply subclass definitions
2857#
2858################################################################
2859
2860
2861# Stats request bodies for desc and table stats are not defined in the
2862# OpenFlow header; We define them here. They are empty classes, really
2863
2864class ofp_desc_stats_request(object):
2865 """
2866 Forced definition of ofp_desc_stats_request (empty class)
2867 """
Rich Lane5de2d942013-01-11 11:49:36 -08002868 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002869 pass
2870 def pack(self, assertstruct=True):
2871 return ""
2872 def unpack(self, binary_string):
2873 return binary_string
2874 def __len__(self):
2875 return 0
2876 def show(self, prefix=''):
2877 return prefix + "ofp_desc_stats_request (empty)\n"
2878 def __eq__(self, other):
2879 return type(self) == type(other)
2880 def __ne__(self, other):
2881 return type(self) != type(other)
2882
2883OFP_DESC_STATS_REQUEST_BYTES = 0
2884
2885class ofp_table_stats_request(object):
2886 """
2887 Forced definition of ofp_table_stats_request (empty class)
2888 """
Rich Lane5de2d942013-01-11 11:49:36 -08002889 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002890 pass
2891 def pack(self, assertstruct=True):
2892 return ""
2893 def unpack(self, binary_string):
2894 return binary_string
2895 def __len__(self):
2896 return 0
2897 def show(self, prefix=''):
2898 return prefix + "ofp_table_stats_request (empty)\n"
2899 def __eq__(self, other):
2900 return type(self) == type(other)
2901 def __ne__(self, other):
2902 return type(self) != type(other)
2903
2904OFP_TABLE_STATS_REQUEST_BYTES = 0
2905
2906class ofp_group_desc_stats_request(object):
2907 """
2908 Forced definition of ofp_group_desc_stats_request (empty class)
2909 """
Rich Lane5de2d942013-01-11 11:49:36 -08002910 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002911 pass
2912 def pack(self, assertstruct=True):
2913 return ""
2914 def unpack(self, binary_string):
2915 return binary_string
2916 def __len__(self):
2917 return 0
2918 def show(self, prefix=''):
2919 return prefix + "ofp_group_desc_stats_request (empty)\n"
2920 def __eq__(self, other):
2921 return type(self) == type(other)
2922 def __ne__(self, other):
2923 return type(self) != type(other)
2924
2925OFP_GROUP_DESC_STATS_REQUEST_BYTES = 0
2926
2927
2928
2929# Stats entries define the content of one element in a stats
2930# reply for the indicated type; define _entry for consistency
2931
2932aggregate_stats_entry = ofp_aggregate_stats_reply
2933desc_stats_entry = ofp_desc_stats
2934port_stats_entry = ofp_port_stats
2935queue_stats_entry = ofp_queue_stats
2936table_stats_entry = ofp_table_stats
2937group_stats_entry = ofp_group_stats
2938group_desc_stats_entry = ofp_group_desc_stats
2939
2940
2941#
2942# Flow stats entry contains an action list of variable length, so
2943# it is done by hand
2944#
2945
2946class flow_stats_entry(ofp_flow_stats):
2947 """
2948 Special case flow stats entry to handle action list object
2949 """
Rich Lane5de2d942013-01-11 11:49:36 -08002950 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002951 ofp_flow_stats.__init__(self)
2952 self.match_fields = match_list()
2953 self.instructions = instruction_list()
2954
2955 def pack(self, assertstruct=True):
2956 self.length = len(self)
2957 if not len(self.match_fields):
2958 tlv_pad = oxm_tlv(0,0,0,0,0,0)
2959 self.match.length += 4
2960 self.match_fields.tlvs.append(tlv_pad)
2961 else:
2962 if len(self.match_fields) > 4:
2963 self.match.length += len(self.match_fields)
2964 packed = ofp_flow_stats.pack(self, assertstruct)
2965 packed += self.match_fields.pack()
2966 padding_size = roundup(len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
2967 padding = [0] * padding_size
2968 if padding_size:
2969 packed += struct.pack("!" + str(padding_size) + "B", *padding)
2970 packed += self.instructions.pack()
2971 if len(packed) != self.length:
2972 print("ERROR: flow_stats_entry pack length not equal",
2973 self.length, len(packed))
2974 return packed
2975
2976 def unpack(self, binary_string):
2977 binary_string = ofp_flow_stats.unpack(self, binary_string)
2978 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
2979 padding = roundup((OFP_FLOW_STATS_BYTES -4) + self.match.length,8) - ((OFP_FLOW_STATS_BYTES - 4) + self.match.length)
2980 if padding:
2981 binary_string = binary_string[padding:]
2982 ai_len = self.length - roundup(OFP_FLOW_STATS_BYTES + len(self.match_fields),8)
2983 if ai_len < 0:
2984 print("ERROR: flow_stats_entry unpack length too small",
2985 self.length)
2986 binary_string = self.instructions.unpack(binary_string, bytes=ai_len)
2987 return binary_string
2988
2989 def __len__(self):
2990 return roundup(OFP_FLOW_STATS_BYTES + len(self.match_fields),8) + len(self.instructions)
2991
2992 def show(self, prefix=''):
2993 outstr = prefix + "flow_stats_entry\n"
2994 outstr += ofp_flow_stats.show(self, prefix + ' ')
2995 outstr += self.match_fields.show(prefix + ' ')
2996 outstr += self.instructions.show(prefix + ' ')
2997 return outstr
2998
2999 def __eq__(self, other):
3000 if type(self) != type(other): return False
3001 return (ofp_flow_stats.__eq__(self, other) and
3002 self.instructions == other.instructions)
3003
3004 def __ne__(self, other): return not self.__eq__(other)
3005
3006
3007class aggregate_stats_request(ofp_stats_request, ofp_aggregate_stats_request):
3008 """
3009 Wrapper class for aggregate stats request message
3010 """
Rich Lane5de2d942013-01-11 11:49:36 -08003011 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003012 self.header = ofp_header()
3013 ofp_stats_request.__init__(self)
3014 ofp_aggregate_stats_request.__init__(self)
3015 self.header.type = OFPT_STATS_REQUEST
3016 self.type = OFPST_AGGREGATE
3017 self.match_fields = match_list()
Rich Lane5de2d942013-01-11 11:49:36 -08003018 for (k, v) in kwargs.items():
3019 if hasattr(self, k):
3020 setattr(self, k, v)
3021 else:
3022 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003023
3024 def pack(self, assertstruct=True):
3025 self.header.length = len(self)
3026 packed = self.header.pack()
3027 packed += ofp_stats_request.pack(self)
3028 if not len(self.match_fields):
3029 tlv_pad = oxm_tlv(0,0,0,0,0,0)
3030 self.match.length += 4
3031 self.match_fields.tlvs.append(tlv_pad)
3032 else:
3033 if len(self.match_fields) > 4:
3034 self.match.length += len(self.match_fields)
3035 packed += ofp_aggregate_stats_request.pack(self, assertstruct)
3036 packed += self.match_fields.pack()
3037 padding_size = roundup(len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
3038 padding = [0] * padding_size
3039
3040 if padding_size:
3041 packed += struct.pack("!" + str(padding_size) + "B", *padding)
3042 return packed
3043
3044 def unpack(self, binary_string):
3045 binary_string = self.header.unpack(binary_string)
3046 binary_string = ofp_stats_request.unpack(self, binary_string)
3047 binary_string = ofp_aggregate_stats_request.unpack(self, binary_string)
3048 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
3049 padding = roundup(OFP_AGGREGATE_STATS_REQUEST_BYTES + len(self.match_fields),8) - (OFP_AGGREGATE_STATS_REQUEST_BYTES + len(self.match_fields))
3050 if padding:
3051 binary_string = binary_string[padding:]
3052 if len(binary_string) != 0:
3053 print "ERROR unpacking flow: extra data"
3054 return binary_string
3055
3056
3057 def __len__(self):
3058 length = len(self.header) + OFP_STATS_REQUEST_BYTES + \
3059 OFP_AGGREGATE_STATS_REQUEST_BYTES
3060 if not len(self.match_fields):
3061 return length + 4
3062 else:
3063 return roundup(length + len(self.match_fields),8)
3064
3065 def show(self, prefix=''):
3066 outstr = prefix + "aggregate_stats_request\n"
3067 outstr += prefix + "ofp header:\n"
3068 outstr += self.header.show(prefix + ' ')
3069 outstr += ofp_stats_request.show(self)
3070 outstr += ofp_aggregate_stats_request.show(self)
3071 return outstr
3072
3073 def __eq__(self, other):
3074 if type(self) != type(other): return False
3075 return (self.header == other.header and
3076 ofp_stats_request.__eq__(self, other) and
3077 ofp_aggregate_stats_request.__eq__(self, other))
3078
3079 def __ne__(self, other): return not self.__eq__(other)
3080
3081
3082class aggregate_stats_reply(ofp_stats_reply):
3083 """
3084 Wrapper class for aggregate stats reply
3085 """
Rich Lane5de2d942013-01-11 11:49:36 -08003086 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003087 self.header = ofp_header()
3088 ofp_stats_reply.__init__(self)
3089 self.header.type = OFPT_STATS_REPLY
3090 self.type = OFPST_AGGREGATE
3091 # stats: Array of type aggregate_stats_entry
3092 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003093 for (k, v) in kwargs.items():
3094 if hasattr(self, k):
3095 setattr(self, k, v)
3096 else:
3097 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003098
3099 def pack(self, assertstruct=True):
3100 self.header.length = len(self)
3101 packed = self.header.pack()
3102 packed += ofp_stats_reply.pack(self)
3103 for obj in self.stats:
3104 packed += obj.pack()
3105 return packed
3106
3107 def unpack(self, binary_string):
3108 binary_string = self.header.unpack(binary_string)
3109 binary_string = ofp_stats_reply.unpack(self, binary_string)
3110 dummy = aggregate_stats_entry()
3111 while len(binary_string) >= len(dummy):
3112 obj = aggregate_stats_entry()
3113 binary_string = obj.unpack(binary_string)
3114 self.stats.append(obj)
3115 if len(binary_string) != 0:
3116 print "ERROR unpacking aggregate stats string: extra bytes"
3117 return binary_string
3118
3119 def __len__(self):
3120 length = len(self.header) + OFP_STATS_REPLY_BYTES
3121 for obj in self.stats:
3122 length += len(obj)
3123 return length
3124
3125 def show(self, prefix=''):
3126 outstr = prefix + "aggregate_stats_reply\n"
3127 outstr += prefix + "ofp header:\n"
3128 outstr += self.header.show(prefix + ' ')
3129 outstr += ofp_stats_reply.show(self)
3130 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3131 for obj in self.stats:
3132 outstr += obj.show()
3133 return outstr
3134
3135 def __eq__(self, other):
3136 if type(self) != type(other): return False
3137 return (self.header == other.header and
3138 ofp_stats_reply.__eq__(self, other) and
3139 self.stats == other.stats)
3140
3141 def __ne__(self, other): return not self.__eq__(other)
3142
3143
3144class desc_stats_request(ofp_stats_request, ofp_desc_stats_request):
3145 """
3146 Wrapper class for desc stats request message
3147 """
Rich Lane5de2d942013-01-11 11:49:36 -08003148 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003149 self.header = ofp_header()
3150 ofp_stats_request.__init__(self)
3151 ofp_desc_stats_request.__init__(self)
3152 self.header.type = OFPT_STATS_REQUEST
3153 self.type = OFPST_DESC
Rich Lane5de2d942013-01-11 11:49:36 -08003154 for (k, v) in kwargs.items():
3155 if hasattr(self, k):
3156 setattr(self, k, v)
3157 else:
3158 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003159
3160 def pack(self, assertstruct=True):
3161 self.header.length = len(self)
3162 packed = self.header.pack()
3163 packed += ofp_stats_request.pack(self)
3164 packed += ofp_desc_stats_request.pack(self)
3165 return packed
3166
3167 def unpack(self, binary_string):
3168 binary_string = self.header.unpack(binary_string)
3169 binary_string = ofp_stats_request.unpack(self, binary_string)
3170 binary_string = ofp_desc_stats_request.unpack(self, binary_string)
3171 if len(binary_string) != 0:
3172 print "ERROR unpacking desc: extra data"
3173 return binary_string
3174
3175 def __len__(self):
3176 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3177 OFP_DESC_STATS_REQUEST_BYTES
3178
3179 def show(self, prefix=''):
3180 outstr = prefix + "desc_stats_request\n"
3181 outstr += prefix + "ofp header:\n"
3182 outstr += self.header.show(prefix + ' ')
3183 outstr += ofp_stats_request.show(self)
3184 outstr += ofp_desc_stats_request.show(self)
3185 return outstr
3186
3187 def __eq__(self, other):
3188 if type(self) != type(other): return False
3189 return (self.header == other.header and
3190 ofp_stats_request.__eq__(self, other) and
3191 ofp_desc_stats_request.__eq__(self, other))
3192
3193 def __ne__(self, other): return not self.__eq__(other)
3194
3195
3196class desc_stats_reply(ofp_stats_reply):
3197 """
3198 Wrapper class for desc stats reply
3199 """
Rich Lane5de2d942013-01-11 11:49:36 -08003200 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003201 self.header = ofp_header()
3202 ofp_stats_reply.__init__(self)
3203 self.header.type = OFPT_STATS_REPLY
3204 self.type = OFPST_DESC
3205 # stats: Array of type desc_stats_entry
3206 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003207 for (k, v) in kwargs.items():
3208 if hasattr(self, k):
3209 setattr(self, k, v)
3210 else:
3211 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003212
3213 def pack(self, assertstruct=True):
3214 self.header.length = len(self)
3215 packed = self.header.pack()
3216 packed += ofp_stats_reply.pack(self)
3217 for obj in self.stats:
3218 packed += obj.pack()
3219 return packed
3220
3221 def unpack(self, binary_string):
3222 binary_string = self.header.unpack(binary_string)
3223 binary_string = ofp_stats_reply.unpack(self, binary_string)
3224 dummy = desc_stats_entry()
3225 while len(binary_string) >= len(dummy):
3226 obj = desc_stats_entry()
3227 binary_string = obj.unpack(binary_string)
3228 self.stats.append(obj)
3229 if len(binary_string) != 0:
3230 print "ERROR unpacking desc stats string: extra bytes"
3231 return binary_string
3232
3233 def __len__(self):
3234 length = len(self.header) + OFP_STATS_REPLY_BYTES
3235 for obj in self.stats:
3236 length += len(obj)
3237 return length
3238
3239 def show(self, prefix=''):
3240 outstr = prefix + "desc_stats_reply\n"
3241 outstr += prefix + "ofp header:\n"
3242 outstr += self.header.show(prefix + ' ')
3243 outstr += ofp_stats_reply.show(self)
3244 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3245 for obj in self.stats:
3246 outstr += obj.show()
3247 return outstr
3248
3249 def __eq__(self, other):
3250 if type(self) != type(other): return False
3251 return (self.header == other.header and
3252 ofp_stats_reply.__eq__(self, other) and
3253 self.stats == other.stats)
3254
3255 def __ne__(self, other): return not self.__eq__(other)
3256
3257
3258class flow_stats_request(ofp_stats_request, ofp_flow_stats_request):
3259 """
3260 Wrapper class for flow stats request message
3261 """
Rich Lane5de2d942013-01-11 11:49:36 -08003262 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003263 self.header = ofp_header()
3264 ofp_stats_request.__init__(self)
3265 ofp_flow_stats_request.__init__(self)
3266 self.header.type = OFPT_STATS_REQUEST
3267 self.type = OFPST_FLOW
3268 self.match_fields = match_list()
Rich Lane5de2d942013-01-11 11:49:36 -08003269 for (k, v) in kwargs.items():
3270 if hasattr(self, k):
3271 setattr(self, k, v)
3272 else:
3273 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003274
3275 def pack(self):
3276 self.header.length = len(self)
3277 packed = self.header.pack()
3278 packed += ofp_stats_request.pack(self)
3279 if not len(self.match_fields):
3280 tlv_pad = oxm_tlv(0,0,0,0,0,0)
3281 self.match.length += 4
3282 self.match_fields.tlvs.append(tlv_pad)
3283 else:
3284 if len(self.match_fields) > 4:
3285 self.match.length += len(self.match_fields)
3286 packed += ofp_flow_stats_request.pack(self)
3287 packed += self.match_fields.pack()
3288 padding_size = roundup(len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
3289 padding = [0] * padding_size
3290 if padding_size:
3291 packed += struct.pack("!" + str(padding_size) + "B", *padding)
3292 return packed
3293
3294 def unpack(self, binary_string):
3295 binary_string = self.header.unpack(binary_string)
3296 binary_string = ofp_stats_request.unpack(self, binary_string)
3297 binary_string = ofp_flow_stats_request.unpack(self, binary_string)
3298 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
3299 padding = roundup(OFP_FLOW_STATS_REQUEST_BYTES + len(self.match_fields),8) - (OFP_FLOW_STATS_REQUEST_BYTES + len(self.match_fields))
3300 if padding:
3301 binary_string = binary_string[padding:]
3302 if len(binary_string) != 0:
3303 print "ERROR unpacking flow: extra data"
3304 return binary_string
3305
3306 def __len__(self):
3307 length = len(self.header) + OFP_STATS_REQUEST_BYTES + \
3308 OFP_FLOW_STATS_REQUEST_BYTES
3309 if not len(self.match_fields):
3310 return length + 4
3311 else:
3312 return roundup(length + len(self.match_fields),8)
3313
3314 def show(self, prefix=''):
3315 outstr = prefix + "flow_stats_request\n"
3316 outstr += prefix + "ofp header:\n"
3317 outstr += self.header.show(prefix + ' ')
3318 outstr += ofp_stats_request.show(self)
3319 outstr += ofp_flow_stats_request.show(self)
3320 outstr += self.match_fields.show(prefix + ' ')
3321 return outstr
3322
3323 def __eq__(self, other):
3324 if type(self) != type(other): return False
3325 return (self.header == other.header and
3326 ofp_stats_request.__eq__(self, other) and
3327 ofp_flow_stats_request.__eq__(self, other) and
3328 self.match_fields != other.match_fields)
3329
3330 def __ne__(self, other): return not self.__eq__(other)
3331
3332
3333class flow_stats_reply(ofp_stats_reply):
3334 """
3335 Wrapper class for flow stats reply
3336 """
Rich Lane5de2d942013-01-11 11:49:36 -08003337 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003338 self.header = ofp_header()
3339 ofp_stats_reply.__init__(self)
3340 self.header.type = OFPT_STATS_REPLY
3341 self.type = OFPST_FLOW
3342 # stats: Array of type flow_stats_entry
3343 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003344 for (k, v) in kwargs.items():
3345 if hasattr(self, k):
3346 setattr(self, k, v)
3347 else:
3348 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003349
3350 def pack(self, assertstruct=True):
3351 self.header.length = len(self)
3352 packed = self.header.pack()
3353 packed += ofp_stats_reply.pack(self)
3354 for obj in self.stats:
3355 packed += obj.pack()
3356 return packed
3357
3358 def unpack(self, binary_string):
3359 binary_string = self.header.unpack(binary_string)
3360 binary_string = ofp_stats_reply.unpack(self, binary_string)
3361 dummy = flow_stats_entry()
3362 while len(binary_string) >= len(dummy):
3363 obj = flow_stats_entry()
3364 binary_string = obj.unpack(binary_string)
3365 self.stats.append(obj)
3366 if len(binary_string) != 0:
3367 print "ERROR unpacking flow stats string: extra bytes"
3368 return binary_string
3369
3370 def __len__(self):
3371 length = len(self.header) + OFP_STATS_REPLY_BYTES
3372 for obj in self.stats:
3373 length += len(obj)
3374 return length
3375
3376 def show(self, prefix=''):
3377 outstr = prefix + "flow_stats_reply\n"
3378 outstr += prefix + "ofp header:\n"
3379 outstr += self.header.show(prefix + ' ')
3380 outstr += ofp_stats_reply.show(self)
3381 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3382 for obj in self.stats:
3383 outstr += obj.show()
3384 return outstr
3385
3386 def __eq__(self, other):
3387 if type(self) != type(other): return False
3388 return (self.header == other.header and
3389 ofp_stats_reply.__eq__(self, other) and
3390 self.stats == other.stats)
3391
3392 def __ne__(self, other): return not self.__eq__(other)
3393
3394
3395class port_stats_request(ofp_stats_request, ofp_port_stats_request):
3396 """
3397 Wrapper class for port stats request message
3398 """
Rich Lane5de2d942013-01-11 11:49:36 -08003399 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003400 self.header = ofp_header()
3401 ofp_stats_request.__init__(self)
3402 ofp_port_stats_request.__init__(self)
3403 self.header.type = OFPT_STATS_REQUEST
3404 self.type = OFPST_PORT
Rich Lane5de2d942013-01-11 11:49:36 -08003405 for (k, v) in kwargs.items():
3406 if hasattr(self, k):
3407 setattr(self, k, v)
3408 else:
3409 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003410
3411 def pack(self, assertstruct=True):
3412 self.header.length = len(self)
3413 packed = self.header.pack()
3414 packed += ofp_stats_request.pack(self)
3415 packed += ofp_port_stats_request.pack(self)
3416 return packed
3417
3418 def unpack(self, binary_string):
3419 binary_string = self.header.unpack(binary_string)
3420 binary_string = ofp_stats_request.unpack(self, binary_string)
3421 binary_string = ofp_port_stats_request.unpack(self, binary_string)
3422 if len(binary_string) != 0:
3423 print "ERROR unpacking port: extra data"
3424 return binary_string
3425
3426 def __len__(self):
3427 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3428 OFP_PORT_STATS_REQUEST_BYTES
3429
3430 def show(self, prefix=''):
3431 outstr = prefix + "port_stats_request\n"
3432 outstr += prefix + "ofp header:\n"
3433 outstr += self.header.show(prefix + ' ')
3434 outstr += ofp_stats_request.show(self)
3435 outstr += ofp_port_stats_request.show(self)
3436 return outstr
3437
3438 def __eq__(self, other):
3439 if type(self) != type(other): return False
3440 return (self.header == other.header and
3441 ofp_stats_request.__eq__(self, other) and
3442 ofp_port_stats_request.__eq__(self, other))
3443
3444 def __ne__(self, other): return not self.__eq__(other)
3445
3446
3447class port_stats_reply(ofp_stats_reply):
3448 """
3449 Wrapper class for port stats reply
3450 """
Rich Lane5de2d942013-01-11 11:49:36 -08003451 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003452 self.header = ofp_header()
3453 ofp_stats_reply.__init__(self)
3454 self.header.type = OFPT_STATS_REPLY
3455 self.type = OFPST_PORT
3456 # stats: Array of type port_stats_entry
3457 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003458 for (k, v) in kwargs.items():
3459 if hasattr(self, k):
3460 setattr(self, k, v)
3461 else:
3462 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003463
3464 def pack(self, assertstruct=True):
3465 self.header.length = len(self)
3466 packed = self.header.pack()
3467 packed += ofp_stats_reply.pack(self)
3468 for obj in self.stats:
3469 packed += obj.pack()
3470 return packed
3471
3472 def unpack(self, binary_string):
3473 binary_string = self.header.unpack(binary_string)
3474 binary_string = ofp_stats_reply.unpack(self, binary_string)
3475 dummy = port_stats_entry()
3476 while len(binary_string) >= len(dummy):
3477 obj = port_stats_entry()
3478 binary_string = obj.unpack(binary_string)
3479 self.stats.append(obj)
3480 if len(binary_string) != 0:
3481 print "ERROR unpacking port stats string: extra bytes"
3482 return binary_string
3483
3484 def __len__(self):
3485 length = len(self.header) + OFP_STATS_REPLY_BYTES
3486 for obj in self.stats:
3487 length += len(obj)
3488 return length
3489
3490 def show(self, prefix=''):
3491 outstr = prefix + "port_stats_reply\n"
3492 outstr += prefix + "ofp header:\n"
3493 outstr += self.header.show(prefix + ' ')
3494 outstr += ofp_stats_reply.show(self)
3495 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3496 for obj in self.stats:
3497 outstr += obj.show()
3498 return outstr
3499
3500 def __eq__(self, other):
3501 if type(self) != type(other): return False
3502 return (self.header == other.header and
3503 ofp_stats_reply.__eq__(self, other) and
3504 self.stats == other.stats)
3505
3506 def __ne__(self, other): return not self.__eq__(other)
3507
3508
3509class queue_stats_request(ofp_stats_request, ofp_queue_stats_request):
3510 """
3511 Wrapper class for queue stats request message
3512 """
Rich Lane5de2d942013-01-11 11:49:36 -08003513 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003514 self.header = ofp_header()
3515 ofp_stats_request.__init__(self)
3516 ofp_queue_stats_request.__init__(self)
3517 self.header.type = OFPT_STATS_REQUEST
3518 self.type = OFPST_QUEUE
Rich Lane5de2d942013-01-11 11:49:36 -08003519 for (k, v) in kwargs.items():
3520 if hasattr(self, k):
3521 setattr(self, k, v)
3522 else:
3523 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003524
3525 def pack(self, assertstruct=True):
3526 self.header.length = len(self)
3527 packed = self.header.pack()
3528 packed += ofp_stats_request.pack(self)
3529 packed += ofp_queue_stats_request.pack(self)
3530 return packed
3531
3532 def unpack(self, binary_string):
3533 binary_string = self.header.unpack(binary_string)
3534 binary_string = ofp_stats_request.unpack(self, binary_string)
3535 binary_string = ofp_queue_stats_request.unpack(self, binary_string)
3536 if len(binary_string) != 0:
3537 print "ERROR unpacking queue: extra data"
3538 return binary_string
3539
3540 def __len__(self):
3541 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3542 OFP_QUEUE_STATS_REQUEST_BYTES
3543
3544 def show(self, prefix=''):
3545 outstr = prefix + "queue_stats_request\n"
3546 outstr += prefix + "ofp header:\n"
3547 outstr += self.header.show(prefix + ' ')
3548 outstr += ofp_stats_request.show(self)
3549 outstr += ofp_queue_stats_request.show(self)
3550 return outstr
3551
3552 def __eq__(self, other):
3553 if type(self) != type(other): return False
3554 return (self.header == other.header and
3555 ofp_stats_request.__eq__(self, other) and
3556 ofp_queue_stats_request.__eq__(self, other))
3557
3558 def __ne__(self, other): return not self.__eq__(other)
3559
3560
3561class queue_stats_reply(ofp_stats_reply):
3562 """
3563 Wrapper class for queue stats reply
3564 """
Rich Lane5de2d942013-01-11 11:49:36 -08003565 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003566 self.header = ofp_header()
3567 ofp_stats_reply.__init__(self)
3568 self.header.type = OFPT_STATS_REPLY
3569 self.type = OFPST_QUEUE
3570 # stats: Array of type queue_stats_entry
3571 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003572 for (k, v) in kwargs.items():
3573 if hasattr(self, k):
3574 setattr(self, k, v)
3575 else:
3576 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003577
3578 def pack(self, assertstruct=True):
3579 self.header.length = len(self)
3580 packed = self.header.pack()
3581 packed += ofp_stats_reply.pack(self)
3582 for obj in self.stats:
3583 packed += obj.pack()
3584 return packed
3585
3586 def unpack(self, binary_string):
3587 binary_string = self.header.unpack(binary_string)
3588 binary_string = ofp_stats_reply.unpack(self, binary_string)
3589 dummy = queue_stats_entry()
3590 while len(binary_string) >= len(dummy):
3591 obj = queue_stats_entry()
3592 binary_string = obj.unpack(binary_string)
3593 self.stats.append(obj)
3594 if len(binary_string) != 0:
3595 print "ERROR unpacking queue stats string: extra bytes"
3596 return binary_string
3597
3598 def __len__(self):
3599 length = len(self.header) + OFP_STATS_REPLY_BYTES
3600 for obj in self.stats:
3601 length += len(obj)
3602 return length
3603
3604 def show(self, prefix=''):
3605 outstr = prefix + "queue_stats_reply\n"
3606 outstr += prefix + "ofp header:\n"
3607 outstr += self.header.show(prefix + ' ')
3608 outstr += ofp_stats_reply.show(self)
3609 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3610 for obj in self.stats:
3611 outstr += obj.show()
3612 return outstr
3613
3614 def __eq__(self, other):
3615 if type(self) != type(other): return False
3616 return (self.header == other.header and
3617 ofp_stats_reply.__eq__(self, other) and
3618 self.stats == other.stats)
3619
3620 def __ne__(self, other): return not self.__eq__(other)
3621
3622
3623class group_stats_request(ofp_stats_request, ofp_group_stats_request):
3624 """
3625 Wrapper class for group stats request message
3626 """
Rich Lane5de2d942013-01-11 11:49:36 -08003627 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003628 self.header = ofp_header()
3629 ofp_stats_request.__init__(self)
3630 ofp_group_stats_request.__init__(self)
3631 self.header.type = OFPT_STATS_REQUEST
3632 self.type = OFPST_GROUP
Rich Lane5de2d942013-01-11 11:49:36 -08003633 for (k, v) in kwargs.items():
3634 if hasattr(self, k):
3635 setattr(self, k, v)
3636 else:
3637 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003638
3639 def pack(self, assertstruct=True):
3640 self.header.length = len(self)
3641 packed = self.header.pack()
3642 packed += ofp_stats_request.pack(self)
3643 packed += ofp_group_stats_request.pack(self)
3644 return packed
3645
3646 def unpack(self, binary_string):
3647 binary_string = self.header.unpack(binary_string)
3648 binary_string = ofp_stats_request.unpack(self, binary_string)
3649 binary_string = ofp_group_stats_request.unpack(self, binary_string)
3650 if len(binary_string) != 0:
3651 print "ERROR unpacking group: extra data"
3652 return binary_string
3653
3654 def __len__(self):
3655 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3656 OFP_GROUP_STATS_REQUEST_BYTES
3657
3658 def show(self, prefix=''):
3659 outstr = prefix + "group_stats_request\n"
3660 outstr += prefix + "ofp header:\n"
3661 outstr += self.header.show(prefix + ' ')
3662 outstr += ofp_stats_request.show(self)
3663 outstr += ofp_group_stats_request.show(self)
3664 return outstr
3665
3666 def __eq__(self, other):
3667 if type(self) != type(other): return False
3668 return (self.header == other.header and
3669 ofp_stats_request.__eq__(self, other) and
3670 ofp_group_stats_request.__eq__(self, other))
3671
3672 def __ne__(self, other): return not self.__eq__(other)
3673
3674
3675class group_stats_reply(ofp_stats_reply):
3676 """
3677 Wrapper class for group stats reply
3678 """
Rich Lane5de2d942013-01-11 11:49:36 -08003679 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003680 self.header = ofp_header()
3681 ofp_stats_reply.__init__(self)
3682 self.header.type = OFPT_STATS_REPLY
3683 self.type = OFPST_GROUP
3684 # stats: Array of type group_stats_entry
3685 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003686 for (k, v) in kwargs.items():
3687 if hasattr(self, k):
3688 setattr(self, k, v)
3689 else:
3690 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003691
3692 def pack(self, assertstruct=True):
3693 self.header.length = len(self)
3694 packed = self.header.pack()
3695 packed += ofp_stats_reply.pack(self)
3696 for obj in self.stats:
3697 packed += obj.pack()
3698 return packed
3699
3700 def unpack(self, binary_string):
3701 binary_string = self.header.unpack(binary_string)
3702 binary_string = ofp_stats_reply.unpack(self, binary_string)
3703 dummy = group_stats_entry()
3704 while len(binary_string) >= len(dummy):
3705 obj = group_stats_entry()
3706 binary_string = obj.unpack(binary_string)
3707 self.stats.append(obj)
3708 if len(binary_string) != 0:
3709 print "ERROR unpacking group stats string: extra bytes"
3710 return binary_string
3711
3712 def __len__(self):
3713 length = len(self.header) + OFP_STATS_REPLY_BYTES
3714 for obj in self.stats:
3715 length += len(obj)
3716 return length
3717
3718 def show(self, prefix=''):
3719 outstr = prefix + "group_stats_reply\n"
3720 outstr += prefix + "ofp header:\n"
3721 outstr += self.header.show(prefix + ' ')
3722 outstr += ofp_stats_reply.show(self)
3723 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3724 for obj in self.stats:
3725 outstr += obj.show()
3726 return outstr
3727
3728 def __eq__(self, other):
3729 if type(self) != type(other): return False
3730 return (self.header == other.header and
3731 ofp_stats_reply.__eq__(self, other) and
3732 self.stats == other.stats)
3733
3734 def __ne__(self, other): return not self.__eq__(other)
3735
3736
3737class group_desc_stats_request(ofp_stats_request, ofp_group_desc_stats_request):
3738 """
3739 Wrapper class for group_desc stats request message
3740 """
Rich Lane5de2d942013-01-11 11:49:36 -08003741 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003742 self.header = ofp_header()
3743 ofp_stats_request.__init__(self)
3744 ofp_group_desc_stats_request.__init__(self)
3745 self.header.type = OFPT_STATS_REQUEST
3746 self.type = OFPST_GROUP_DESC
Rich Lane5de2d942013-01-11 11:49:36 -08003747 for (k, v) in kwargs.items():
3748 if hasattr(self, k):
3749 setattr(self, k, v)
3750 else:
3751 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003752
3753 def pack(self, assertstruct=True):
3754 self.header.length = len(self)
3755 packed = self.header.pack()
3756 packed += ofp_stats_request.pack(self)
3757 packed += ofp_group_desc_stats_request.pack(self)
3758 return packed
3759
3760 def unpack(self, binary_string):
3761 binary_string = self.header.unpack(binary_string)
3762 binary_string = ofp_stats_request.unpack(self, binary_string)
3763 binary_string = ofp_group_desc_stats_request.unpack(self, binary_string)
3764 if len(binary_string) != 0:
3765 print "ERROR unpacking group_desc: extra data"
3766 return binary_string
3767
3768 def __len__(self):
3769 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3770 OFP_GROUP_DESC_STATS_REQUEST_BYTES
3771
3772 def show(self, prefix=''):
3773 outstr = prefix + "group_desc_stats_request\n"
3774 outstr += prefix + "ofp header:\n"
3775 outstr += self.header.show(prefix + ' ')
3776 outstr += ofp_stats_request.show(self)
3777 outstr += ofp_group_desc_stats_request.show(self)
3778 return outstr
3779
3780 def __eq__(self, other):
3781 if type(self) != type(other): return False
3782 return (self.header == other.header and
3783 ofp_stats_request.__eq__(self, other) and
3784 ofp_group_desc_stats_request.__eq__(self, other))
3785
3786 def __ne__(self, other): return not self.__eq__(other)
3787
3788
3789class group_desc_stats_reply(ofp_stats_reply):
3790 """
3791 Wrapper class for group_desc stats reply
3792 """
Rich Lane5de2d942013-01-11 11:49:36 -08003793 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003794 self.header = ofp_header()
3795 ofp_stats_reply.__init__(self)
3796 self.header.type = OFPT_STATS_REPLY
3797 self.type = OFPST_GROUP_DESC
3798 # stats: Array of type group_desc_stats_entry
3799 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003800 for (k, v) in kwargs.items():
3801 if hasattr(self, k):
3802 setattr(self, k, v)
3803 else:
3804 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003805
3806 def pack(self, assertstruct=True):
3807 self.header.length = len(self)
3808 packed = self.header.pack()
3809 packed += ofp_stats_reply.pack(self)
3810 for obj in self.stats:
3811 packed += obj.pack()
3812 return packed
3813
3814 def unpack(self, binary_string):
3815 binary_string = self.header.unpack(binary_string)
3816 binary_string = ofp_stats_reply.unpack(self, binary_string)
3817 dummy = group_desc_stats_entry()
3818 while len(binary_string) >= len(dummy):
3819 obj = group_desc_stats_entry()
3820 binary_string = obj.unpack(binary_string)
3821 self.stats.append(obj)
3822 if len(binary_string) != 0:
3823 print "ERROR unpacking group_desc stats string: extra bytes"
3824 return binary_string
3825
3826 def __len__(self):
3827 length = len(self.header) + OFP_STATS_REPLY_BYTES
3828 for obj in self.stats:
3829 length += len(obj)
3830 return length
3831
3832 def show(self, prefix=''):
3833 outstr = prefix + "group_desc_stats_reply\n"
3834 outstr += prefix + "ofp header:\n"
3835 outstr += self.header.show(prefix + ' ')
3836 outstr += ofp_stats_reply.show(self)
3837 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3838 for obj in self.stats:
3839 outstr += obj.show()
3840 return outstr
3841
3842 def __eq__(self, other):
3843 if type(self) != type(other): return False
3844 return (self.header == other.header and
3845 ofp_stats_reply.__eq__(self, other) and
3846 self.stats == other.stats)
3847
3848 def __ne__(self, other): return not self.__eq__(other)
3849
3850
3851class table_stats_request(ofp_stats_request, ofp_table_stats_request):
3852 """
3853 Wrapper class for table stats request message
3854 """
Rich Lane5de2d942013-01-11 11:49:36 -08003855 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003856 self.header = ofp_header()
3857 ofp_stats_request.__init__(self)
3858 ofp_table_stats_request.__init__(self)
3859 self.header.type = OFPT_STATS_REQUEST
3860 self.type = OFPST_TABLE
Rich Lane5de2d942013-01-11 11:49:36 -08003861 for (k, v) in kwargs.items():
3862 if hasattr(self, k):
3863 setattr(self, k, v)
3864 else:
3865 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003866
3867 def pack(self, assertstruct=True):
3868 self.header.length = len(self)
3869 packed = self.header.pack()
3870 packed += ofp_stats_request.pack(self)
3871 packed += ofp_table_stats_request.pack(self)
3872 return packed
3873
3874 def unpack(self, binary_string):
3875 binary_string = self.header.unpack(binary_string)
3876 binary_string = ofp_stats_request.unpack(self, binary_string)
3877 binary_string = ofp_table_stats_request.unpack(self, binary_string)
3878 if len(binary_string) != 0:
3879 print "ERROR unpacking table: extra data"
3880 return binary_string
3881
3882 def __len__(self):
3883 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3884 OFP_TABLE_STATS_REQUEST_BYTES
3885
3886 def show(self, prefix=''):
3887 outstr = prefix + "table_stats_request\n"
3888 outstr += prefix + "ofp header:\n"
3889 outstr += self.header.show(prefix + ' ')
3890 outstr += ofp_stats_request.show(self)
3891 outstr += ofp_table_stats_request.show(self)
3892 return outstr
3893
3894 def __eq__(self, other):
3895 if type(self) != type(other): return False
3896 return (self.header == other.header and
3897 ofp_stats_request.__eq__(self, other) and
3898 ofp_table_stats_request.__eq__(self, other))
3899
3900 def __ne__(self, other): return not self.__eq__(other)
3901
3902
3903class table_stats_reply(ofp_stats_reply):
3904 """
3905 Wrapper class for table stats reply
3906 """
Rich Lane5de2d942013-01-11 11:49:36 -08003907 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003908 self.header = ofp_header()
3909 ofp_stats_reply.__init__(self)
3910 self.header.type = OFPT_STATS_REPLY
3911 self.type = OFPST_TABLE
3912 # stats: Array of type table_stats_entry
3913 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003914 for (k, v) in kwargs.items():
3915 if hasattr(self, k):
3916 setattr(self, k, v)
3917 else:
3918 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003919
3920 def pack(self, assertstruct=True):
3921 self.header.length = len(self)
3922 packed = self.header.pack()
3923 packed += ofp_stats_reply.pack(self)
3924 for obj in self.stats:
3925 packed += obj.pack()
3926 return packed
3927
3928 def unpack(self, binary_string):
3929 binary_string = self.header.unpack(binary_string)
3930 binary_string = ofp_stats_reply.unpack(self, binary_string)
3931 dummy = table_stats_entry()
3932 while len(binary_string) >= len(dummy):
3933 obj = table_stats_entry()
3934 binary_string = obj.unpack(binary_string)
3935 self.stats.append(obj)
3936 if len(binary_string) != 0:
3937 print "ERROR unpacking table stats string: extra bytes"
3938 return binary_string
3939
3940 def __len__(self):
3941 length = len(self.header) + OFP_STATS_REPLY_BYTES
3942 for obj in self.stats:
3943 length += len(obj)
3944 return length
3945
3946 def show(self, prefix=''):
3947 outstr = prefix + "table_stats_reply\n"
3948 outstr += prefix + "ofp header:\n"
3949 outstr += self.header.show(prefix + ' ')
3950 outstr += ofp_stats_reply.show(self)
3951 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3952 for obj in self.stats:
3953 outstr += obj.show()
3954 return outstr
3955
3956 def __eq__(self, other):
3957 if type(self) != type(other): return False
3958 return (self.header == other.header and
3959 ofp_stats_reply.__eq__(self, other) and
3960 self.stats == other.stats)
3961
3962 def __ne__(self, other): return not self.__eq__(other)
3963
3964
3965# @todo Add buckets to group and group_desc stats obejcts"
3966message_type_list = (
3967 aggregate_stats_reply,
3968 aggregate_stats_request,
3969 bad_action_error_msg,
3970 bad_request_error_msg,
3971 barrier_reply,
3972 barrier_request,
3973 desc_stats_reply,
3974 desc_stats_request,
3975 echo_reply,
3976 echo_request,
3977 error,
3978 experimenter,
3979 features_reply,
3980 features_request,
3981 flow_mod,
3982 flow_mod_failed_error_msg,
3983 flow_removed,
3984 flow_stats_reply,
3985 flow_stats_request,
3986 get_config_reply,
3987 get_config_request,
3988 group_desc_stats_request,
3989 group_desc_stats_reply,
3990 group_stats_request,
3991 group_stats_reply,
3992 group_mod,
3993 group_mod_failed_error_msg,
3994 hello,
3995 hello_failed_error_msg,
3996 packet_in,
3997 packet_out,
3998 port_mod,
3999 port_mod_failed_error_msg,
4000 port_stats_reply,
4001 port_stats_request,
4002 port_status,
4003 queue_get_config_reply,
4004 queue_get_config_request,
4005 queue_op_failed_error_msg,
4006 queue_stats_reply,
4007 queue_stats_request,
4008 set_config,
4009 switch_config_failed_error_msg,
4010 table_mod,
4011 table_mod_failed_error_msg,
4012 table_stats_reply,
4013 table_stats_request,
4014 )
4015