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