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