blob: 4f5a43f640a7a3952155558437fdf7c81452835d [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"
Rich Lanee6ea3fe2013-03-08 17:54:38 -0800971 for obj in self.actions:
972 outstr += obj.show(prefix + " ")
Rich Lane6242d9f2013-01-06 17:35:39 -0800973 return outstr
974
975 def __eq__(self, other):
976 """
977 Return True if self and other hold the same data
978
979 @param other Other object in comparison
980
981 """
982 if type(self) != type(other): return False
983 if not self.header.__eq__(other.header): return False
984
985 if not ofp_flow_mod.__eq__(self, other): return False
986 if self.actions != other.actions: return False
987 return True
988
989 def __ne__(self, other):
990 """
991 Return True if self and other do not hold the same data
992
993 @param other Other object in comparison
994
995 """
996 return not self.__eq__(other)
997
998
999class flow_removed(ofp_flow_removed):
1000 """
1001 Wrapper class for flow_removed
1002
1003 OpenFlow message header: length, version, xid, type
1004 @arg length: The total length of the message
1005 @arg version: The OpenFlow version (1)
1006 @arg xid: The transaction ID
1007 @arg type: The message type (OFPT_FLOW_REMOVED=11)
1008
1009 Data members inherited from ofp_flow_removed:
1010 @arg match
1011 @arg cookie
1012 @arg priority
1013 @arg reason
1014 @arg duration_sec
1015 @arg duration_nsec
1016 @arg idle_timeout
1017 @arg packet_count
1018 @arg byte_count
1019
1020 """
1021
1022 def __init__(self, **kwargs):
1023 ofp_flow_removed.__init__(self)
1024 self.header = ofp_header()
1025 self.header.type = OFPT_FLOW_REMOVED
1026 for (k, v) in kwargs.items():
1027 if hasattr(self, k):
1028 setattr(self, k, v)
1029 else:
1030 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1031
1032
1033 def pack(self):
1034 """
1035 Pack object into string
1036
1037 @return The packed string which can go on the wire
1038
1039 """
1040 self.header.length = len(self)
1041 packed = self.header.pack()
1042
1043 packed += ofp_flow_removed.pack(self)
1044 return packed
1045
1046 def unpack(self, binary_string):
1047 """
1048 Unpack object from a binary string
1049
1050 @param binary_string The wire protocol byte string holding the object
1051 represented as an array of bytes.
1052 @return The remainder of binary_string that was not parsed.
1053
1054 """
1055 binary_string = self.header.unpack(binary_string)
1056
1057 binary_string = ofp_flow_removed.unpack(self, binary_string)
1058 # Fixme: If no self.data, add check for data remaining
1059 return binary_string
1060
1061 def __len__(self):
1062 """
1063 Return the length of this object once packed into a string
1064
1065 @return An integer representing the number bytes in the packed
1066 string.
1067
1068 """
1069 length = OFP_HEADER_BYTES
1070
1071 length += ofp_flow_removed.__len__(self)
1072 return length
1073
1074 def show(self, prefix=''):
1075 """
1076 Generate a string (with multiple lines) describing the contents
1077 of the object in a readable manner
1078
1079 @param prefix Pre-pended at the beginning of each line.
1080
1081 """
1082
1083 outstr = prefix + 'flow_removed (OFPT_FLOW_REMOVED)\n'
1084 prefix += ' '
1085 outstr += prefix + 'ofp header\n'
1086 outstr += self.header.show(prefix + ' ')
1087 outstr += ofp_flow_removed.show(self, prefix)
1088 return outstr
1089
1090 def __eq__(self, other):
1091 """
1092 Return True if self and other hold the same data
1093
1094 @param other Other object in comparison
1095
1096 """
1097 if type(self) != type(other): return False
1098 if not self.header.__eq__(other.header): return False
1099
1100 if not ofp_flow_removed.__eq__(self, other): return False
1101 return True
1102
1103 def __ne__(self, other):
1104 """
1105 Return True if self and other do not hold the same data
1106
1107 @param other Other object in comparison
1108
1109 """
1110 return not self.__eq__(other)
1111
1112
1113class get_config_reply(ofp_switch_config):
1114 """
1115 Wrapper class for get_config_reply
1116
1117 OpenFlow message header: length, version, xid, type
1118 @arg length: The total length of the message
1119 @arg version: The OpenFlow version (1)
1120 @arg xid: The transaction ID
1121 @arg type: The message type (OFPT_GET_CONFIG_REPLY=8)
1122
1123 Data members inherited from ofp_switch_config:
1124 @arg flags
1125 @arg miss_send_len
1126
1127 """
1128
1129 def __init__(self, **kwargs):
1130 ofp_switch_config.__init__(self)
1131 self.header = ofp_header()
1132 self.header.type = OFPT_GET_CONFIG_REPLY
1133 for (k, v) in kwargs.items():
1134 if hasattr(self, k):
1135 setattr(self, k, v)
1136 else:
1137 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1138
1139
1140 def pack(self):
1141 """
1142 Pack object into string
1143
1144 @return The packed string which can go on the wire
1145
1146 """
1147 self.header.length = len(self)
1148 packed = self.header.pack()
1149
1150 packed += ofp_switch_config.pack(self)
1151 return packed
1152
1153 def unpack(self, binary_string):
1154 """
1155 Unpack object from a binary string
1156
1157 @param binary_string The wire protocol byte string holding the object
1158 represented as an array of bytes.
1159 @return The remainder of binary_string that was not parsed.
1160
1161 """
1162 binary_string = self.header.unpack(binary_string)
1163
1164 binary_string = ofp_switch_config.unpack(self, binary_string)
1165 # Fixme: If no self.data, add check for data remaining
1166 return binary_string
1167
1168 def __len__(self):
1169 """
1170 Return the length of this object once packed into a string
1171
1172 @return An integer representing the number bytes in the packed
1173 string.
1174
1175 """
1176 length = OFP_HEADER_BYTES
1177
1178 length += ofp_switch_config.__len__(self)
1179 return length
1180
1181 def show(self, prefix=''):
1182 """
1183 Generate a string (with multiple lines) describing the contents
1184 of the object in a readable manner
1185
1186 @param prefix Pre-pended at the beginning of each line.
1187
1188 """
1189
1190 outstr = prefix + 'get_config_reply (OFPT_GET_CONFIG_REPLY)\n'
1191 prefix += ' '
1192 outstr += prefix + 'ofp header\n'
1193 outstr += self.header.show(prefix + ' ')
1194 outstr += ofp_switch_config.show(self, prefix)
1195 return outstr
1196
1197 def __eq__(self, other):
1198 """
1199 Return True if self and other hold the same data
1200
1201 @param other Other object in comparison
1202
1203 """
1204 if type(self) != type(other): return False
1205 if not self.header.__eq__(other.header): return False
1206
1207 if not ofp_switch_config.__eq__(self, other): return False
1208 return True
1209
1210 def __ne__(self, other):
1211 """
1212 Return True if self and other do not hold the same data
1213
1214 @param other Other object in comparison
1215
1216 """
1217 return not self.__eq__(other)
1218
1219
1220class get_config_request:
1221 """
1222 Wrapper class for get_config_request
1223
1224 OpenFlow message header: length, version, xid, type
1225 @arg length: The total length of the message
1226 @arg version: The OpenFlow version (1)
1227 @arg xid: The transaction ID
1228 @arg type: The message type (OFPT_GET_CONFIG_REQUEST=7)
1229
1230
1231 """
1232
1233 def __init__(self, **kwargs):
1234 self.header = ofp_header()
1235 self.header.type = OFPT_GET_CONFIG_REQUEST
1236 for (k, v) in kwargs.items():
1237 if hasattr(self, k):
1238 setattr(self, k, v)
1239 else:
1240 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1241
1242
1243 def pack(self):
1244 """
1245 Pack object into string
1246
1247 @return The packed string which can go on the wire
1248
1249 """
1250 self.header.length = len(self)
1251 packed = self.header.pack()
1252
1253 return packed
1254
1255 def unpack(self, binary_string):
1256 """
1257 Unpack object from a binary string
1258
1259 @param binary_string The wire protocol byte string holding the object
1260 represented as an array of bytes.
1261 @return The remainder of binary_string that was not parsed.
1262
1263 """
1264 binary_string = self.header.unpack(binary_string)
1265
1266 # Fixme: If no self.data, add check for data remaining
1267 return binary_string
1268
1269 def __len__(self):
1270 """
1271 Return the length of this object once packed into a string
1272
1273 @return An integer representing the number bytes in the packed
1274 string.
1275
1276 """
1277 length = OFP_HEADER_BYTES
1278
1279 return length
1280
1281 def show(self, prefix=''):
1282 """
1283 Generate a string (with multiple lines) describing the contents
1284 of the object in a readable manner
1285
1286 @param prefix Pre-pended at the beginning of each line.
1287
1288 """
1289
1290 outstr = prefix + 'get_config_request (OFPT_GET_CONFIG_REQUEST)\n'
1291 prefix += ' '
1292 outstr += prefix + 'ofp header\n'
1293 outstr += self.header.show(prefix + ' ')
1294 return outstr
1295
1296 def __eq__(self, other):
1297 """
1298 Return True if self and other hold the same data
1299
1300 @param other Other object in comparison
1301
1302 """
1303 if type(self) != type(other): return False
1304 if not self.header.__eq__(other.header): return False
1305
1306 return True
1307
1308 def __ne__(self, other):
1309 """
1310 Return True if self and other do not hold the same data
1311
1312 @param other Other object in comparison
1313
1314 """
1315 return not self.__eq__(other)
1316
1317
1318class hello:
1319 """
1320 Wrapper class for hello
1321
1322 OpenFlow message header: length, version, xid, type
1323 @arg length: The total length of the message
1324 @arg version: The OpenFlow version (1)
1325 @arg xid: The transaction ID
1326 @arg type: The message type (OFPT_HELLO=0)
1327
1328 @arg data: Binary string following message members
1329
1330 """
1331
1332 def __init__(self, **kwargs):
1333 self.header = ofp_header()
1334 self.header.type = OFPT_HELLO
1335 self.data = ""
1336 for (k, v) in kwargs.items():
1337 if hasattr(self, k):
1338 setattr(self, k, v)
1339 else:
1340 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1341
1342
1343 def pack(self):
1344 """
1345 Pack object into string
1346
1347 @return The packed string which can go on the wire
1348
1349 """
1350 self.header.length = len(self)
1351 packed = self.header.pack()
1352
1353 packed += self.data
1354 return packed
1355
1356 def unpack(self, binary_string):
1357 """
1358 Unpack object from a binary string
1359
1360 @param binary_string The wire protocol byte string holding the object
1361 represented as an array of bytes.
1362 @return The remainder of binary_string that was not parsed.
1363
1364 """
1365 binary_string = self.header.unpack(binary_string)
1366
1367 self.data = binary_string
1368 binary_string = ''
1369 return binary_string
1370
1371 def __len__(self):
1372 """
1373 Return the length of this object once packed into a string
1374
1375 @return An integer representing the number bytes in the packed
1376 string.
1377
1378 """
1379 length = OFP_HEADER_BYTES
1380
1381 length += len(self.data)
1382 return length
1383
1384 def show(self, prefix=''):
1385 """
1386 Generate a string (with multiple lines) describing the contents
1387 of the object in a readable manner
1388
1389 @param prefix Pre-pended at the beginning of each line.
1390
1391 """
1392
1393 outstr = prefix + 'hello (OFPT_HELLO)\n'
1394 prefix += ' '
1395 outstr += prefix + 'ofp header\n'
1396 outstr += self.header.show(prefix + ' ')
1397 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1398 ##@todo Fix this circular reference
1399 # if len(self.data) > 0:
1400 # obj = of_message_parse(self.data)
1401 # if obj != None:
1402 # outstr += obj.show(prefix)
1403 # else:
1404 # outstr += prefix + "Unable to parse data\n"
1405 return outstr
1406
1407 def __eq__(self, other):
1408 """
1409 Return True if self and other hold the same data
1410
1411 @param other Other object in comparison
1412
1413 """
1414 if type(self) != type(other): return False
1415 if not self.header.__eq__(other.header): return False
1416
1417 if self.data != other.data: return False
1418 return True
1419
1420 def __ne__(self, other):
1421 """
1422 Return True if self and other do not hold the same data
1423
1424 @param other Other object in comparison
1425
1426 """
1427 return not self.__eq__(other)
1428
1429
1430class packet_in(ofp_packet_in):
1431 """
1432 Wrapper class for packet_in
1433
1434 OpenFlow message header: length, version, xid, type
1435 @arg length: The total length of the message
1436 @arg version: The OpenFlow version (1)
1437 @arg xid: The transaction ID
1438 @arg type: The message type (OFPT_PACKET_IN=10)
1439
1440 Data members inherited from ofp_packet_in:
1441 @arg buffer_id
1442 @arg total_len
1443 @arg in_port
1444 @arg reason
1445 @arg data: Binary string following message members
1446
1447 """
1448
1449 def __init__(self, **kwargs):
1450 ofp_packet_in.__init__(self)
1451 self.header = ofp_header()
1452 self.header.type = OFPT_PACKET_IN
1453 self.data = ""
1454 for (k, v) in kwargs.items():
1455 if hasattr(self, k):
1456 setattr(self, k, v)
1457 else:
1458 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1459
1460
1461 def pack(self):
1462 """
1463 Pack object into string
1464
1465 @return The packed string which can go on the wire
1466
1467 """
1468 self.header.length = len(self)
1469 packed = self.header.pack()
1470
1471 packed += ofp_packet_in.pack(self)
1472 packed += self.data
1473 return packed
1474
1475 def unpack(self, binary_string):
1476 """
1477 Unpack object from a binary string
1478
1479 @param binary_string The wire protocol byte string holding the object
1480 represented as an array of bytes.
1481 @return The remainder of binary_string that was not parsed.
1482
1483 """
1484 binary_string = self.header.unpack(binary_string)
1485
1486 binary_string = ofp_packet_in.unpack(self, binary_string)
1487 self.data = binary_string
1488 binary_string = ''
1489 return binary_string
1490
1491 def __len__(self):
1492 """
1493 Return the length of this object once packed into a string
1494
1495 @return An integer representing the number bytes in the packed
1496 string.
1497
1498 """
1499 length = OFP_HEADER_BYTES
1500
1501 length += ofp_packet_in.__len__(self)
1502 length += len(self.data)
1503 return length
1504
1505 def show(self, prefix=''):
1506 """
1507 Generate a string (with multiple lines) describing the contents
1508 of the object in a readable manner
1509
1510 @param prefix Pre-pended at the beginning of each line.
1511
1512 """
1513
1514 outstr = prefix + 'packet_in (OFPT_PACKET_IN)\n'
1515 prefix += ' '
1516 outstr += prefix + 'ofp header\n'
1517 outstr += self.header.show(prefix + ' ')
1518 outstr += ofp_packet_in.show(self, prefix)
1519 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1520 ##@todo Fix this circular reference
1521 # if len(self.data) > 0:
1522 # obj = of_message_parse(self.data)
1523 # if obj != None:
1524 # outstr += obj.show(prefix)
1525 # else:
1526 # outstr += prefix + "Unable to parse data\n"
1527 return outstr
1528
1529 def __eq__(self, other):
1530 """
1531 Return True if self and other hold the same data
1532
1533 @param other Other object in comparison
1534
1535 """
1536 if type(self) != type(other): return False
1537 if not self.header.__eq__(other.header): return False
1538
1539 if not ofp_packet_in.__eq__(self, other): return False
1540 if self.data != other.data: return False
1541 return True
1542
1543 def __ne__(self, other):
1544 """
1545 Return True if self and other do not hold the same data
1546
1547 @param other Other object in comparison
1548
1549 """
1550 return not self.__eq__(other)
1551
1552
1553class packet_out(ofp_packet_out):
1554 """
1555 Wrapper class for packet_out
1556
1557 OpenFlow message header: length, version, xid, type
1558 @arg length: The total length of the message
1559 @arg version: The OpenFlow version (1)
1560 @arg xid: The transaction ID
1561 @arg type: The message type (OFPT_PACKET_OUT=13)
1562
1563 Data members inherited from ofp_packet_out:
1564 @arg buffer_id
1565 @arg in_port
1566 @arg actions_len
1567 @arg actions: Object of type action_list
1568 @arg data: Binary string following message members
1569
1570 """
1571
1572 def __init__(self, **kwargs):
1573 ofp_packet_out.__init__(self)
1574 self.header = ofp_header()
1575 self.header.type = OFPT_PACKET_OUT
1576 self.actions = []
1577 self.data = ""
1578 for (k, v) in kwargs.items():
1579 if hasattr(self, k):
1580 setattr(self, k, v)
1581 else:
1582 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1583 # Coerce keyword arg into list type
1584 self.actions = action_list(self.actions)
1585
1586
1587 def pack(self):
1588 """
1589 Pack object into string
1590
1591 @return The packed string which can go on the wire
1592
1593 """
1594 self.header.length = len(self)
1595 packed = self.header.pack()
1596
1597 self.actions_len = len(self.actions)
1598 packed += ofp_packet_out.pack(self)
1599 packed += self.actions.pack()
1600 packed += self.data
1601 return packed
1602
1603 def unpack(self, binary_string):
1604 """
1605 Unpack object from a binary string
1606
1607 @param binary_string The wire protocol byte string holding the object
1608 represented as an array of bytes.
1609 @return The remainder of binary_string that was not parsed.
1610
1611 """
1612 binary_string = self.header.unpack(binary_string)
1613
1614 binary_string = ofp_packet_out.unpack(self, binary_string)
1615 binary_string = self.actions.unpack(binary_string, bytes=self.actions_len)
1616 self.data = binary_string
1617 binary_string = ''
1618 return binary_string
1619
1620 def __len__(self):
1621 """
1622 Return the length of this object once packed into a string
1623
1624 @return An integer representing the number bytes in the packed
1625 string.
1626
1627 """
1628 length = OFP_HEADER_BYTES
1629
1630 length += ofp_packet_out.__len__(self)
1631 length += len(self.actions)
1632 length += len(self.data)
1633 return length
1634
1635 def show(self, prefix=''):
1636 """
1637 Generate a string (with multiple lines) describing the contents
1638 of the object in a readable manner
1639
1640 @param prefix Pre-pended at the beginning of each line.
1641
1642 """
1643
1644 outstr = prefix + 'packet_out (OFPT_PACKET_OUT)\n'
1645 prefix += ' '
1646 outstr += prefix + 'ofp header\n'
1647 outstr += self.header.show(prefix + ' ')
1648 outstr += ofp_packet_out.show(self, prefix)
1649 outstr += prefix + "List actions\n"
Rich Lanee6ea3fe2013-03-08 17:54:38 -08001650 for obj in self.actions:
1651 outstr += obj.show(prefix + " ")
Rich Lane6242d9f2013-01-06 17:35:39 -08001652 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1653 ##@todo Fix this circular reference
1654 # if len(self.data) > 0:
1655 # obj = of_message_parse(self.data)
1656 # if obj != None:
1657 # outstr += obj.show(prefix)
1658 # else:
1659 # outstr += prefix + "Unable to parse data\n"
1660 return outstr
1661
1662 def __eq__(self, other):
1663 """
1664 Return True if self and other hold the same data
1665
1666 @param other Other object in comparison
1667
1668 """
1669 if type(self) != type(other): return False
1670 if not self.header.__eq__(other.header): return False
1671
1672 if not ofp_packet_out.__eq__(self, other): return False
1673 if self.data != other.data: return False
1674 if self.actions != other.actions: return False
1675 return True
1676
1677 def __ne__(self, other):
1678 """
1679 Return True if self and other do not hold the same data
1680
1681 @param other Other object in comparison
1682
1683 """
1684 return not self.__eq__(other)
1685
1686
1687class port_mod(ofp_port_mod):
1688 """
1689 Wrapper class for port_mod
1690
1691 OpenFlow message header: length, version, xid, type
1692 @arg length: The total length of the message
1693 @arg version: The OpenFlow version (1)
1694 @arg xid: The transaction ID
1695 @arg type: The message type (OFPT_PORT_MOD=15)
1696
1697 Data members inherited from ofp_port_mod:
1698 @arg port_no
1699 @arg hw_addr
1700 @arg config
1701 @arg mask
1702 @arg advertise
1703
1704 """
1705
1706 def __init__(self, **kwargs):
1707 ofp_port_mod.__init__(self)
1708 self.header = ofp_header()
1709 self.header.type = OFPT_PORT_MOD
1710 for (k, v) in kwargs.items():
1711 if hasattr(self, k):
1712 setattr(self, k, v)
1713 else:
1714 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1715
1716
1717 def pack(self):
1718 """
1719 Pack object into string
1720
1721 @return The packed string which can go on the wire
1722
1723 """
1724 self.header.length = len(self)
1725 packed = self.header.pack()
1726
1727 packed += ofp_port_mod.pack(self)
1728 return packed
1729
1730 def unpack(self, binary_string):
1731 """
1732 Unpack object from a binary string
1733
1734 @param binary_string The wire protocol byte string holding the object
1735 represented as an array of bytes.
1736 @return The remainder of binary_string that was not parsed.
1737
1738 """
1739 binary_string = self.header.unpack(binary_string)
1740
1741 binary_string = ofp_port_mod.unpack(self, binary_string)
1742 # Fixme: If no self.data, add check for data remaining
1743 return binary_string
1744
1745 def __len__(self):
1746 """
1747 Return the length of this object once packed into a string
1748
1749 @return An integer representing the number bytes in the packed
1750 string.
1751
1752 """
1753 length = OFP_HEADER_BYTES
1754
1755 length += ofp_port_mod.__len__(self)
1756 return length
1757
1758 def show(self, prefix=''):
1759 """
1760 Generate a string (with multiple lines) describing the contents
1761 of the object in a readable manner
1762
1763 @param prefix Pre-pended at the beginning of each line.
1764
1765 """
1766
1767 outstr = prefix + 'port_mod (OFPT_PORT_MOD)\n'
1768 prefix += ' '
1769 outstr += prefix + 'ofp header\n'
1770 outstr += self.header.show(prefix + ' ')
1771 outstr += ofp_port_mod.show(self, prefix)
1772 return outstr
1773
1774 def __eq__(self, other):
1775 """
1776 Return True if self and other hold the same data
1777
1778 @param other Other object in comparison
1779
1780 """
1781 if type(self) != type(other): return False
1782 if not self.header.__eq__(other.header): return False
1783
1784 if not ofp_port_mod.__eq__(self, other): return False
1785 return True
1786
1787 def __ne__(self, other):
1788 """
1789 Return True if self and other do not hold the same data
1790
1791 @param other Other object in comparison
1792
1793 """
1794 return not self.__eq__(other)
1795
1796
1797class port_status(ofp_port_status):
1798 """
1799 Wrapper class for port_status
1800
1801 OpenFlow message header: length, version, xid, type
1802 @arg length: The total length of the message
1803 @arg version: The OpenFlow version (1)
1804 @arg xid: The transaction ID
1805 @arg type: The message type (OFPT_PORT_STATUS=12)
1806
1807 Data members inherited from ofp_port_status:
1808 @arg reason
1809 @arg desc
1810
1811 """
1812
1813 def __init__(self, **kwargs):
1814 ofp_port_status.__init__(self)
1815 self.header = ofp_header()
1816 self.header.type = OFPT_PORT_STATUS
1817 for (k, v) in kwargs.items():
1818 if hasattr(self, k):
1819 setattr(self, k, v)
1820 else:
1821 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1822
1823
1824 def pack(self):
1825 """
1826 Pack object into string
1827
1828 @return The packed string which can go on the wire
1829
1830 """
1831 self.header.length = len(self)
1832 packed = self.header.pack()
1833
1834 packed += ofp_port_status.pack(self)
1835 return packed
1836
1837 def unpack(self, binary_string):
1838 """
1839 Unpack object from a binary string
1840
1841 @param binary_string The wire protocol byte string holding the object
1842 represented as an array of bytes.
1843 @return The remainder of binary_string that was not parsed.
1844
1845 """
1846 binary_string = self.header.unpack(binary_string)
1847
1848 binary_string = ofp_port_status.unpack(self, binary_string)
1849 # Fixme: If no self.data, add check for data remaining
1850 return binary_string
1851
1852 def __len__(self):
1853 """
1854 Return the length of this object once packed into a string
1855
1856 @return An integer representing the number bytes in the packed
1857 string.
1858
1859 """
1860 length = OFP_HEADER_BYTES
1861
1862 length += ofp_port_status.__len__(self)
1863 return length
1864
1865 def show(self, prefix=''):
1866 """
1867 Generate a string (with multiple lines) describing the contents
1868 of the object in a readable manner
1869
1870 @param prefix Pre-pended at the beginning of each line.
1871
1872 """
1873
1874 outstr = prefix + 'port_status (OFPT_PORT_STATUS)\n'
1875 prefix += ' '
1876 outstr += prefix + 'ofp header\n'
1877 outstr += self.header.show(prefix + ' ')
1878 outstr += ofp_port_status.show(self, prefix)
1879 return outstr
1880
1881 def __eq__(self, other):
1882 """
1883 Return True if self and other hold the same data
1884
1885 @param other Other object in comparison
1886
1887 """
1888 if type(self) != type(other): return False
1889 if not self.header.__eq__(other.header): return False
1890
1891 if not ofp_port_status.__eq__(self, other): return False
1892 return True
1893
1894 def __ne__(self, other):
1895 """
1896 Return True if self and other do not hold the same data
1897
1898 @param other Other object in comparison
1899
1900 """
1901 return not self.__eq__(other)
1902
1903
1904class queue_get_config_reply(ofp_queue_get_config_reply):
1905 """
1906 Wrapper class for queue_get_config_reply
1907
1908 OpenFlow message header: length, version, xid, type
1909 @arg length: The total length of the message
1910 @arg version: The OpenFlow version (1)
1911 @arg xid: The transaction ID
1912 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REPLY=21)
1913
1914 Data members inherited from ofp_queue_get_config_reply:
1915 @arg port
1916 @arg queues: Variable length array of TBD
1917
1918 """
1919
1920 def __init__(self, **kwargs):
1921 ofp_queue_get_config_reply.__init__(self)
1922 self.header = ofp_header()
1923 self.header.type = OFPT_QUEUE_GET_CONFIG_REPLY
1924 self.queues = []
1925 for (k, v) in kwargs.items():
1926 if hasattr(self, k):
1927 setattr(self, k, v)
1928 else:
1929 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1930
1931
1932 def pack(self):
1933 """
1934 Pack object into string
1935
1936 @return The packed string which can go on the wire
1937
1938 """
1939 self.header.length = len(self)
1940 packed = self.header.pack()
1941
1942 packed += ofp_queue_get_config_reply.pack(self)
1943 for obj in self.queues:
1944 packed += obj.pack()
1945 return packed
1946
1947 def unpack(self, binary_string):
1948 """
1949 Unpack object from a binary string
1950
1951 @param binary_string The wire protocol byte string holding the object
1952 represented as an array of bytes.
1953 @return The remainder of binary_string that was not parsed.
1954
1955 """
1956 binary_string = self.header.unpack(binary_string)
1957
1958 binary_string = ofp_queue_get_config_reply.unpack(self, binary_string)
1959 for obj in self.queues:
1960 binary_string = obj.unpack(binary_string)
1961 # Fixme: If no self.data, add check for data remaining
1962 return binary_string
1963
1964 def __len__(self):
1965 """
1966 Return the length of this object once packed into a string
1967
1968 @return An integer representing the number bytes in the packed
1969 string.
1970
1971 """
1972 length = OFP_HEADER_BYTES
1973
1974 length += ofp_queue_get_config_reply.__len__(self)
1975 for obj in self.queues:
1976 length += len(obj)
1977 return length
1978
1979 def show(self, prefix=''):
1980 """
1981 Generate a string (with multiple lines) describing the contents
1982 of the object in a readable manner
1983
1984 @param prefix Pre-pended at the beginning of each line.
1985
1986 """
1987
1988 outstr = prefix + 'queue_get_config_reply (OFPT_QUEUE_GET_CONFIG_REPLY)\n'
1989 prefix += ' '
1990 outstr += prefix + 'ofp header\n'
1991 outstr += self.header.show(prefix + ' ')
1992 outstr += ofp_queue_get_config_reply.show(self, prefix)
1993 outstr += prefix + "Array queues\n"
1994 for obj in self.queues:
1995 outstr += obj.show(prefix + ' ')
1996 return outstr
1997
1998 def __eq__(self, other):
1999 """
2000 Return True if self and other hold the same data
2001
2002 @param other Other object in comparison
2003
2004 """
2005 if type(self) != type(other): return False
2006 if not self.header.__eq__(other.header): return False
2007
2008 if not ofp_queue_get_config_reply.__eq__(self, other): return False
2009 if self.queues != other.queues: return False
2010 return True
2011
2012 def __ne__(self, other):
2013 """
2014 Return True if self and other do not hold the same data
2015
2016 @param other Other object in comparison
2017
2018 """
2019 return not self.__eq__(other)
2020
2021
2022class queue_get_config_request(ofp_queue_get_config_request):
2023 """
2024 Wrapper class for queue_get_config_request
2025
2026 OpenFlow message header: length, version, xid, type
2027 @arg length: The total length of the message
2028 @arg version: The OpenFlow version (1)
2029 @arg xid: The transaction ID
2030 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REQUEST=20)
2031
2032 Data members inherited from ofp_queue_get_config_request:
2033 @arg port
2034
2035 """
2036
2037 def __init__(self, **kwargs):
2038 ofp_queue_get_config_request.__init__(self)
2039 self.header = ofp_header()
2040 self.header.type = OFPT_QUEUE_GET_CONFIG_REQUEST
2041 for (k, v) in kwargs.items():
2042 if hasattr(self, k):
2043 setattr(self, k, v)
2044 else:
2045 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2046
2047
2048 def pack(self):
2049 """
2050 Pack object into string
2051
2052 @return The packed string which can go on the wire
2053
2054 """
2055 self.header.length = len(self)
2056 packed = self.header.pack()
2057
2058 packed += ofp_queue_get_config_request.pack(self)
2059 return packed
2060
2061 def unpack(self, binary_string):
2062 """
2063 Unpack object from a binary string
2064
2065 @param binary_string The wire protocol byte string holding the object
2066 represented as an array of bytes.
2067 @return The remainder of binary_string that was not parsed.
2068
2069 """
2070 binary_string = self.header.unpack(binary_string)
2071
2072 binary_string = ofp_queue_get_config_request.unpack(self, binary_string)
2073 # Fixme: If no self.data, add check for data remaining
2074 return binary_string
2075
2076 def __len__(self):
2077 """
2078 Return the length of this object once packed into a string
2079
2080 @return An integer representing the number bytes in the packed
2081 string.
2082
2083 """
2084 length = OFP_HEADER_BYTES
2085
2086 length += ofp_queue_get_config_request.__len__(self)
2087 return length
2088
2089 def show(self, prefix=''):
2090 """
2091 Generate a string (with multiple lines) describing the contents
2092 of the object in a readable manner
2093
2094 @param prefix Pre-pended at the beginning of each line.
2095
2096 """
2097
2098 outstr = prefix + 'queue_get_config_request (OFPT_QUEUE_GET_CONFIG_REQUEST)\n'
2099 prefix += ' '
2100 outstr += prefix + 'ofp header\n'
2101 outstr += self.header.show(prefix + ' ')
2102 outstr += ofp_queue_get_config_request.show(self, prefix)
2103 return outstr
2104
2105 def __eq__(self, other):
2106 """
2107 Return True if self and other hold the same data
2108
2109 @param other Other object in comparison
2110
2111 """
2112 if type(self) != type(other): return False
2113 if not self.header.__eq__(other.header): return False
2114
2115 if not ofp_queue_get_config_request.__eq__(self, other): return False
2116 return True
2117
2118 def __ne__(self, other):
2119 """
2120 Return True if self and other do not hold the same data
2121
2122 @param other Other object in comparison
2123
2124 """
2125 return not self.__eq__(other)
2126
2127
2128class set_config(ofp_switch_config):
2129 """
2130 Wrapper class for set_config
2131
2132 OpenFlow message header: length, version, xid, type
2133 @arg length: The total length of the message
2134 @arg version: The OpenFlow version (1)
2135 @arg xid: The transaction ID
2136 @arg type: The message type (OFPT_SET_CONFIG=9)
2137
2138 Data members inherited from ofp_switch_config:
2139 @arg flags
2140 @arg miss_send_len
2141
2142 """
2143
2144 def __init__(self, **kwargs):
2145 ofp_switch_config.__init__(self)
2146 self.header = ofp_header()
2147 self.header.type = OFPT_SET_CONFIG
2148 for (k, v) in kwargs.items():
2149 if hasattr(self, k):
2150 setattr(self, k, v)
2151 else:
2152 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2153
2154
2155 def pack(self):
2156 """
2157 Pack object into string
2158
2159 @return The packed string which can go on the wire
2160
2161 """
2162 self.header.length = len(self)
2163 packed = self.header.pack()
2164
2165 packed += ofp_switch_config.pack(self)
2166 return packed
2167
2168 def unpack(self, binary_string):
2169 """
2170 Unpack object from a binary string
2171
2172 @param binary_string The wire protocol byte string holding the object
2173 represented as an array of bytes.
2174 @return The remainder of binary_string that was not parsed.
2175
2176 """
2177 binary_string = self.header.unpack(binary_string)
2178
2179 binary_string = ofp_switch_config.unpack(self, binary_string)
2180 # Fixme: If no self.data, add check for data remaining
2181 return binary_string
2182
2183 def __len__(self):
2184 """
2185 Return the length of this object once packed into a string
2186
2187 @return An integer representing the number bytes in the packed
2188 string.
2189
2190 """
2191 length = OFP_HEADER_BYTES
2192
2193 length += ofp_switch_config.__len__(self)
2194 return length
2195
2196 def show(self, prefix=''):
2197 """
2198 Generate a string (with multiple lines) describing the contents
2199 of the object in a readable manner
2200
2201 @param prefix Pre-pended at the beginning of each line.
2202
2203 """
2204
2205 outstr = prefix + 'set_config (OFPT_SET_CONFIG)\n'
2206 prefix += ' '
2207 outstr += prefix + 'ofp header\n'
2208 outstr += self.header.show(prefix + ' ')
2209 outstr += ofp_switch_config.show(self, prefix)
2210 return outstr
2211
2212 def __eq__(self, other):
2213 """
2214 Return True if self and other hold the same data
2215
2216 @param other Other object in comparison
2217
2218 """
2219 if type(self) != type(other): return False
2220 if not self.header.__eq__(other.header): return False
2221
2222 if not ofp_switch_config.__eq__(self, other): return False
2223 return True
2224
2225 def __ne__(self, other):
2226 """
2227 Return True if self and other do not hold the same data
2228
2229 @param other Other object in comparison
2230
2231 """
2232 return not self.__eq__(other)
2233
2234
2235class stats_reply(ofp_stats_reply):
2236 """
2237 Wrapper class for stats_reply
2238
2239 OpenFlow message header: length, version, xid, type
2240 @arg length: The total length of the message
2241 @arg version: The OpenFlow version (1)
2242 @arg xid: The transaction ID
2243 @arg type: The message type (OFPT_STATS_REPLY=17)
2244
2245 Data members inherited from ofp_stats_reply:
2246 @arg type
2247 @arg flags
2248
2249 """
2250
2251 def __init__(self, **kwargs):
2252 ofp_stats_reply.__init__(self)
2253 self.header = ofp_header()
2254 self.header.type = OFPT_STATS_REPLY
2255 for (k, v) in kwargs.items():
2256 if hasattr(self, k):
2257 setattr(self, k, v)
2258 else:
2259 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2260
2261
2262 def pack(self):
2263 """
2264 Pack object into string
2265
2266 @return The packed string which can go on the wire
2267
2268 """
2269 self.header.length = len(self)
2270 packed = self.header.pack()
2271
2272 packed += ofp_stats_reply.pack(self)
2273 return packed
2274
2275 def unpack(self, binary_string):
2276 """
2277 Unpack object from a binary string
2278
2279 @param binary_string The wire protocol byte string holding the object
2280 represented as an array of bytes.
2281 @return The remainder of binary_string that was not parsed.
2282
2283 """
2284 binary_string = self.header.unpack(binary_string)
2285
2286 binary_string = ofp_stats_reply.unpack(self, binary_string)
2287 # Fixme: If no self.data, add check for data remaining
2288 return binary_string
2289
2290 def __len__(self):
2291 """
2292 Return the length of this object once packed into a string
2293
2294 @return An integer representing the number bytes in the packed
2295 string.
2296
2297 """
2298 length = OFP_HEADER_BYTES
2299
2300 length += ofp_stats_reply.__len__(self)
2301 return length
2302
2303 def show(self, prefix=''):
2304 """
2305 Generate a string (with multiple lines) describing the contents
2306 of the object in a readable manner
2307
2308 @param prefix Pre-pended at the beginning of each line.
2309
2310 """
2311
2312 outstr = prefix + 'stats_reply (OFPT_STATS_REPLY)\n'
2313 prefix += ' '
2314 outstr += prefix + 'ofp header\n'
2315 outstr += self.header.show(prefix + ' ')
2316 outstr += ofp_stats_reply.show(self, prefix)
2317 return outstr
2318
2319 def __eq__(self, other):
2320 """
2321 Return True if self and other hold the same data
2322
2323 @param other Other object in comparison
2324
2325 """
2326 if type(self) != type(other): return False
2327 if not self.header.__eq__(other.header): return False
2328
2329 if not ofp_stats_reply.__eq__(self, other): return False
2330 return True
2331
2332 def __ne__(self, other):
2333 """
2334 Return True if self and other do not hold the same data
2335
2336 @param other Other object in comparison
2337
2338 """
2339 return not self.__eq__(other)
2340
2341
2342class stats_request(ofp_stats_request):
2343 """
2344 Wrapper class for stats_request
2345
2346 OpenFlow message header: length, version, xid, type
2347 @arg length: The total length of the message
2348 @arg version: The OpenFlow version (1)
2349 @arg xid: The transaction ID
2350 @arg type: The message type (OFPT_STATS_REQUEST=16)
2351
2352 Data members inherited from ofp_stats_request:
2353 @arg type
2354 @arg flags
2355
2356 """
2357
2358 def __init__(self, **kwargs):
2359 ofp_stats_request.__init__(self)
2360 self.header = ofp_header()
2361 self.header.type = OFPT_STATS_REQUEST
2362 for (k, v) in kwargs.items():
2363 if hasattr(self, k):
2364 setattr(self, k, v)
2365 else:
2366 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2367
2368
2369 def pack(self):
2370 """
2371 Pack object into string
2372
2373 @return The packed string which can go on the wire
2374
2375 """
2376 self.header.length = len(self)
2377 packed = self.header.pack()
2378
2379 packed += ofp_stats_request.pack(self)
2380 return packed
2381
2382 def unpack(self, binary_string):
2383 """
2384 Unpack object from a binary string
2385
2386 @param binary_string The wire protocol byte string holding the object
2387 represented as an array of bytes.
2388 @return The remainder of binary_string that was not parsed.
2389
2390 """
2391 binary_string = self.header.unpack(binary_string)
2392
2393 binary_string = ofp_stats_request.unpack(self, binary_string)
2394 # Fixme: If no self.data, add check for data remaining
2395 return binary_string
2396
2397 def __len__(self):
2398 """
2399 Return the length of this object once packed into a string
2400
2401 @return An integer representing the number bytes in the packed
2402 string.
2403
2404 """
2405 length = OFP_HEADER_BYTES
2406
2407 length += ofp_stats_request.__len__(self)
2408 return length
2409
2410 def show(self, prefix=''):
2411 """
2412 Generate a string (with multiple lines) describing the contents
2413 of the object in a readable manner
2414
2415 @param prefix Pre-pended at the beginning of each line.
2416
2417 """
2418
2419 outstr = prefix + 'stats_request (OFPT_STATS_REQUEST)\n'
2420 prefix += ' '
2421 outstr += prefix + 'ofp header\n'
2422 outstr += self.header.show(prefix + ' ')
2423 outstr += ofp_stats_request.show(self, prefix)
2424 return outstr
2425
2426 def __eq__(self, other):
2427 """
2428 Return True if self and other hold the same data
2429
2430 @param other Other object in comparison
2431
2432 """
2433 if type(self) != type(other): return False
2434 if not self.header.__eq__(other.header): return False
2435
2436 if not ofp_stats_request.__eq__(self, other): return False
2437 return True
2438
2439 def __ne__(self, other):
2440 """
2441 Return True if self and other do not hold the same data
2442
2443 @param other Other object in comparison
2444
2445 """
2446 return not self.__eq__(other)
2447
2448
2449class vendor(ofp_vendor_header):
2450 """
2451 Wrapper class for vendor
2452
2453 OpenFlow message header: length, version, xid, type
2454 @arg length: The total length of the message
2455 @arg version: The OpenFlow version (1)
2456 @arg xid: The transaction ID
2457 @arg type: The message type (OFPT_VENDOR=4)
2458
2459 Data members inherited from ofp_vendor_header:
2460 @arg vendor
2461 @arg data: Binary string following message members
2462
2463 """
2464
2465 def __init__(self, **kwargs):
2466 ofp_vendor_header.__init__(self)
2467 self.header = ofp_header()
2468 self.header.type = OFPT_VENDOR
2469 self.data = ""
2470 for (k, v) in kwargs.items():
2471 if hasattr(self, k):
2472 setattr(self, k, v)
2473 else:
2474 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2475
2476
2477 def pack(self):
2478 """
2479 Pack object into string
2480
2481 @return The packed string which can go on the wire
2482
2483 """
2484 self.header.length = len(self)
2485 packed = self.header.pack()
2486
2487 packed += ofp_vendor_header.pack(self)
2488 packed += self.data
2489 return packed
2490
2491 def unpack(self, binary_string):
2492 """
2493 Unpack object from a binary string
2494
2495 @param binary_string The wire protocol byte string holding the object
2496 represented as an array of bytes.
2497 @return The remainder of binary_string that was not parsed.
2498
2499 """
2500 binary_string = self.header.unpack(binary_string)
2501
2502 binary_string = ofp_vendor_header.unpack(self, binary_string)
2503 self.data = binary_string
2504 binary_string = ''
2505 return binary_string
2506
2507 def __len__(self):
2508 """
2509 Return the length of this object once packed into a string
2510
2511 @return An integer representing the number bytes in the packed
2512 string.
2513
2514 """
2515 length = OFP_HEADER_BYTES
2516
2517 length += ofp_vendor_header.__len__(self)
2518 length += len(self.data)
2519 return length
2520
2521 def show(self, prefix=''):
2522 """
2523 Generate a string (with multiple lines) describing the contents
2524 of the object in a readable manner
2525
2526 @param prefix Pre-pended at the beginning of each line.
2527
2528 """
2529
2530 outstr = prefix + 'vendor (OFPT_VENDOR)\n'
2531 prefix += ' '
2532 outstr += prefix + 'ofp header\n'
2533 outstr += self.header.show(prefix + ' ')
2534 outstr += ofp_vendor_header.show(self, prefix)
2535 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
2536 ##@todo Fix this circular reference
2537 # if len(self.data) > 0:
2538 # obj = of_message_parse(self.data)
2539 # if obj != None:
2540 # outstr += obj.show(prefix)
2541 # else:
2542 # outstr += prefix + "Unable to parse data\n"
2543 return outstr
2544
2545 def __eq__(self, other):
2546 """
2547 Return True if self and other hold the same data
2548
2549 @param other Other object in comparison
2550
2551 """
2552 if type(self) != type(other): return False
2553 if not self.header.__eq__(other.header): return False
2554
2555 if not ofp_vendor_header.__eq__(self, other): return False
2556 if self.data != other.data: return False
2557 return True
2558
2559 def __ne__(self, other):
2560 """
2561 Return True if self and other do not hold the same data
2562
2563 @param other Other object in comparison
2564
2565 """
2566 return not self.__eq__(other)
2567
2568
2569
2570################################################################
2571#
2572# Stats request and reply subclass definitions
2573#
2574################################################################
2575
2576
2577# Stats request bodies for desc and table stats are not defined in the
2578# OpenFlow header; We define them here. They are empty classes, really
2579
2580class ofp_desc_stats_request:
2581 """
2582 Forced definition of ofp_desc_stats_request (empty class)
2583 """
2584 def __init__(self):
2585 pass
2586 def pack(self, assertstruct=True):
2587 return ""
2588 def unpack(self, binary_string):
2589 return binary_string
2590 def __len__(self):
2591 return 0
2592 def show(self, prefix=''):
2593 return prefix + "ofp_desc_stats_request (empty)\n"
2594 def __eq__(self, other):
2595 return type(self) == type(other)
2596 def __ne__(self, other):
2597 return type(self) != type(other)
2598
2599OFP_DESC_STATS_REQUEST_BYTES = 0
2600
2601class ofp_table_stats_request:
2602 """
2603 Forced definition of ofp_table_stats_request (empty class)
2604 """
2605 def __init__(self):
2606 pass
2607 def pack(self, assertstruct=True):
2608 return ""
2609 def unpack(self, binary_string):
2610 return binary_string
2611 def __len__(self):
2612 return 0
2613 def show(self, prefix=''):
2614 return prefix + "ofp_table_stats_request (empty)\n"
2615 def __eq__(self, other):
2616 return type(self) == type(other)
2617 def __ne__(self, other):
2618 return type(self) != type(other)
2619
2620OFP_TABLE_STATS_REQUEST_BYTES = 0
2621
2622
2623
2624# Stats entries define the content of one element in a stats
2625# reply for the indicated type; define _entry for consistency
2626
2627aggregate_stats_entry = ofp_aggregate_stats_reply
2628desc_stats_entry = ofp_desc_stats
2629port_stats_entry = ofp_port_stats
2630queue_stats_entry = ofp_queue_stats
2631table_stats_entry = ofp_table_stats
2632
2633
2634#
2635# Flow stats entry contains an action list of variable length, so
2636# it is done by hand
2637#
2638
2639class flow_stats_entry(ofp_flow_stats):
2640 """
2641 Special case flow stats entry to handle action list object
2642 """
2643 def __init__(self):
2644 ofp_flow_stats.__init__(self)
2645 self.actions = action_list()
2646
2647 def pack(self, assertstruct=True):
2648 self.length = len(self)
2649 packed = ofp_flow_stats.pack(self, assertstruct)
2650 packed += self.actions.pack()
2651 if len(packed) != self.length:
2652 print("ERROR: flow_stats_entry pack length not equal",
2653 self.length, len(packed))
2654 return packed
2655
2656 def unpack(self, binary_string):
2657 binary_string = ofp_flow_stats.unpack(self, binary_string)
2658 ai_len = self.length - OFP_FLOW_STATS_BYTES
2659 if ai_len < 0:
2660 print("ERROR: flow_stats_entry unpack length too small",
2661 self.length)
2662 binary_string = self.actions.unpack(binary_string, bytes=ai_len)
2663 return binary_string
2664
2665 def __len__(self):
2666 return OFP_FLOW_STATS_BYTES + len(self.actions)
2667
2668 def show(self, prefix=''):
2669 outstr = prefix + "flow_stats_entry\n"
2670 outstr += ofp_flow_stats.show(self, prefix + ' ')
Rich Lanee6ea3fe2013-03-08 17:54:38 -08002671 outstr += prefix + "List actions\n"
2672 for obj in self.actions:
2673 outstr += obj.show(prefix + ' ')
Rich Lane6242d9f2013-01-06 17:35:39 -08002674 return outstr
2675
2676 def __eq__(self, other):
2677 if type(self) != type(other): return False
2678 return (ofp_flow_stats.__eq__(self, other) and
2679 self.actions == other.actions)
2680
2681 def __ne__(self, other): return not self.__eq__(other)
2682
2683
2684class aggregate_stats_request(ofp_stats_request, ofp_aggregate_stats_request):
2685 """
2686 Wrapper class for aggregate stats request message
2687 """
2688 def __init__(self, **kwargs):
2689 self.header = ofp_header()
2690 ofp_stats_request.__init__(self)
2691 ofp_aggregate_stats_request.__init__(self)
2692 self.header.type = OFPT_STATS_REQUEST
2693 self.type = OFPST_AGGREGATE
2694 for (k, v) in kwargs.items():
2695 if hasattr(self, k):
2696 setattr(self, k, v)
2697 else:
2698 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2699
2700 def pack(self, assertstruct=True):
2701 self.header.length = len(self)
2702 packed = self.header.pack()
2703 packed += ofp_stats_request.pack(self)
2704 packed += ofp_aggregate_stats_request.pack(self)
2705 return packed
2706
2707 def unpack(self, binary_string):
2708 binary_string = self.header.unpack(binary_string)
2709 binary_string = ofp_stats_request.unpack(self, binary_string)
2710 binary_string = ofp_aggregate_stats_request.unpack(self, binary_string)
2711 if len(binary_string) != 0:
2712 print "ERROR unpacking aggregate: extra data"
2713 return binary_string
2714
2715 def __len__(self):
2716 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
2717 OFP_AGGREGATE_STATS_REQUEST_BYTES
2718
2719 def show(self, prefix=''):
2720 outstr = prefix + "aggregate_stats_request\n"
2721 outstr += prefix + "ofp header:\n"
2722 outstr += self.header.show(prefix + ' ')
2723 outstr += ofp_stats_request.show(self)
2724 outstr += ofp_aggregate_stats_request.show(self)
2725 return outstr
2726
2727 def __eq__(self, other):
2728 if type(self) != type(other): return False
2729 return (self.header == other.header and
2730 ofp_stats_request.__eq__(self, other) and
2731 ofp_aggregate_stats_request.__eq__(self, other))
2732
2733 def __ne__(self, other): return not self.__eq__(other)
2734
2735
2736class aggregate_stats_reply(ofp_stats_reply):
2737 """
2738 Wrapper class for aggregate stats reply
2739 """
2740 def __init__(self):
2741 self.header = ofp_header()
2742 ofp_stats_reply.__init__(self)
2743 self.header.type = OFPT_STATS_REPLY
2744 self.type = OFPST_AGGREGATE
2745 # stats: Array of type aggregate_stats_entry
2746 self.stats = []
2747
2748 def pack(self, assertstruct=True):
2749 self.header.length = len(self)
2750 packed = self.header.pack()
2751 packed += ofp_stats_reply.pack(self)
2752 for obj in self.stats:
2753 packed += obj.pack()
2754 return packed
2755
2756 def unpack(self, binary_string):
2757 binary_string = self.header.unpack(binary_string)
2758 binary_string = ofp_stats_reply.unpack(self, binary_string)
2759 dummy = aggregate_stats_entry()
2760 while len(binary_string) >= len(dummy):
2761 obj = aggregate_stats_entry()
2762 binary_string = obj.unpack(binary_string)
2763 self.stats.append(obj)
2764 if len(binary_string) != 0:
2765 print "ERROR unpacking aggregate stats string: extra bytes"
2766 return binary_string
2767
2768 def __len__(self):
2769 length = len(self.header) + OFP_STATS_REPLY_BYTES
2770 for obj in self.stats:
2771 length += len(obj)
2772 return length
2773
2774 def show(self, prefix=''):
2775 outstr = prefix + "aggregate_stats_reply\n"
2776 outstr += prefix + "ofp header:\n"
2777 outstr += self.header.show(prefix + ' ')
2778 outstr += ofp_stats_reply.show(self)
2779 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
2780 for obj in self.stats:
2781 outstr += obj.show()
2782 return outstr
2783
2784 def __eq__(self, other):
2785 if type(self) != type(other): return False
2786 return (self.header == other.header and
2787 ofp_stats_reply.__eq__(self, other) and
2788 self.stats == other.stats)
2789
2790 def __ne__(self, other): return not self.__eq__(other)
2791
2792
2793class desc_stats_request(ofp_stats_request, ofp_desc_stats_request):
2794 """
2795 Wrapper class for desc stats request message
2796 """
2797 def __init__(self, **kwargs):
2798 self.header = ofp_header()
2799 ofp_stats_request.__init__(self)
2800 ofp_desc_stats_request.__init__(self)
2801 self.header.type = OFPT_STATS_REQUEST
2802 self.type = OFPST_DESC
2803 for (k, v) in kwargs.items():
2804 if hasattr(self, k):
2805 setattr(self, k, v)
2806 else:
2807 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2808
2809 def pack(self, assertstruct=True):
2810 self.header.length = len(self)
2811 packed = self.header.pack()
2812 packed += ofp_stats_request.pack(self)
2813 packed += ofp_desc_stats_request.pack(self)
2814 return packed
2815
2816 def unpack(self, binary_string):
2817 binary_string = self.header.unpack(binary_string)
2818 binary_string = ofp_stats_request.unpack(self, binary_string)
2819 binary_string = ofp_desc_stats_request.unpack(self, binary_string)
2820 if len(binary_string) != 0:
2821 print "ERROR unpacking desc: extra data"
2822 return binary_string
2823
2824 def __len__(self):
2825 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
2826 OFP_DESC_STATS_REQUEST_BYTES
2827
2828 def show(self, prefix=''):
2829 outstr = prefix + "desc_stats_request\n"
2830 outstr += prefix + "ofp header:\n"
2831 outstr += self.header.show(prefix + ' ')
2832 outstr += ofp_stats_request.show(self)
2833 outstr += ofp_desc_stats_request.show(self)
2834 return outstr
2835
2836 def __eq__(self, other):
2837 if type(self) != type(other): return False
2838 return (self.header == other.header and
2839 ofp_stats_request.__eq__(self, other) and
2840 ofp_desc_stats_request.__eq__(self, other))
2841
2842 def __ne__(self, other): return not self.__eq__(other)
2843
2844
2845class desc_stats_reply(ofp_stats_reply):
2846 """
2847 Wrapper class for desc stats reply
2848 """
2849 def __init__(self):
2850 self.header = ofp_header()
2851 ofp_stats_reply.__init__(self)
2852 self.header.type = OFPT_STATS_REPLY
2853 self.type = OFPST_DESC
2854 # stats: Array of type desc_stats_entry
2855 self.stats = []
2856
2857 def pack(self, assertstruct=True):
2858 self.header.length = len(self)
2859 packed = self.header.pack()
2860 packed += ofp_stats_reply.pack(self)
2861 for obj in self.stats:
2862 packed += obj.pack()
2863 return packed
2864
2865 def unpack(self, binary_string):
2866 binary_string = self.header.unpack(binary_string)
2867 binary_string = ofp_stats_reply.unpack(self, binary_string)
2868 dummy = desc_stats_entry()
2869 while len(binary_string) >= len(dummy):
2870 obj = desc_stats_entry()
2871 binary_string = obj.unpack(binary_string)
2872 self.stats.append(obj)
2873 if len(binary_string) != 0:
2874 print "ERROR unpacking desc stats string: extra bytes"
2875 return binary_string
2876
2877 def __len__(self):
2878 length = len(self.header) + OFP_STATS_REPLY_BYTES
2879 for obj in self.stats:
2880 length += len(obj)
2881 return length
2882
2883 def show(self, prefix=''):
2884 outstr = prefix + "desc_stats_reply\n"
2885 outstr += prefix + "ofp header:\n"
2886 outstr += self.header.show(prefix + ' ')
2887 outstr += ofp_stats_reply.show(self)
2888 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
2889 for obj in self.stats:
2890 outstr += obj.show()
2891 return outstr
2892
2893 def __eq__(self, other):
2894 if type(self) != type(other): return False
2895 return (self.header == other.header and
2896 ofp_stats_reply.__eq__(self, other) and
2897 self.stats == other.stats)
2898
2899 def __ne__(self, other): return not self.__eq__(other)
2900
2901
2902class flow_stats_request(ofp_stats_request, ofp_flow_stats_request):
2903 """
2904 Wrapper class for flow stats request message
2905 """
2906 def __init__(self, **kwargs):
2907 self.header = ofp_header()
2908 ofp_stats_request.__init__(self)
2909 ofp_flow_stats_request.__init__(self)
2910 self.header.type = OFPT_STATS_REQUEST
2911 self.type = OFPST_FLOW
2912 for (k, v) in kwargs.items():
2913 if hasattr(self, k):
2914 setattr(self, k, v)
2915 else:
2916 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2917
2918 def pack(self, assertstruct=True):
2919 self.header.length = len(self)
2920 packed = self.header.pack()
2921 packed += ofp_stats_request.pack(self)
2922 packed += ofp_flow_stats_request.pack(self)
2923 return packed
2924
2925 def unpack(self, binary_string):
2926 binary_string = self.header.unpack(binary_string)
2927 binary_string = ofp_stats_request.unpack(self, binary_string)
2928 binary_string = ofp_flow_stats_request.unpack(self, binary_string)
2929 if len(binary_string) != 0:
2930 print "ERROR unpacking flow: extra data"
2931 return binary_string
2932
2933 def __len__(self):
2934 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
2935 OFP_FLOW_STATS_REQUEST_BYTES
2936
2937 def show(self, prefix=''):
2938 outstr = prefix + "flow_stats_request\n"
2939 outstr += prefix + "ofp header:\n"
2940 outstr += self.header.show(prefix + ' ')
2941 outstr += ofp_stats_request.show(self)
2942 outstr += ofp_flow_stats_request.show(self)
2943 return outstr
2944
2945 def __eq__(self, other):
2946 if type(self) != type(other): return False
2947 return (self.header == other.header and
2948 ofp_stats_request.__eq__(self, other) and
2949 ofp_flow_stats_request.__eq__(self, other))
2950
2951 def __ne__(self, other): return not self.__eq__(other)
2952
2953
2954class flow_stats_reply(ofp_stats_reply):
2955 """
2956 Wrapper class for flow stats reply
2957 """
2958 def __init__(self):
2959 self.header = ofp_header()
2960 ofp_stats_reply.__init__(self)
2961 self.header.type = OFPT_STATS_REPLY
2962 self.type = OFPST_FLOW
2963 # stats: Array of type flow_stats_entry
2964 self.stats = []
2965
2966 def pack(self, assertstruct=True):
2967 self.header.length = len(self)
2968 packed = self.header.pack()
2969 packed += ofp_stats_reply.pack(self)
2970 for obj in self.stats:
2971 packed += obj.pack()
2972 return packed
2973
2974 def unpack(self, binary_string):
2975 binary_string = self.header.unpack(binary_string)
2976 binary_string = ofp_stats_reply.unpack(self, binary_string)
2977 dummy = flow_stats_entry()
2978 while len(binary_string) >= len(dummy):
2979 obj = flow_stats_entry()
2980 binary_string = obj.unpack(binary_string)
2981 self.stats.append(obj)
2982 if len(binary_string) != 0:
2983 print "ERROR unpacking flow stats string: extra bytes"
2984 return binary_string
2985
2986 def __len__(self):
2987 length = len(self.header) + OFP_STATS_REPLY_BYTES
2988 for obj in self.stats:
2989 length += len(obj)
2990 return length
2991
2992 def show(self, prefix=''):
2993 outstr = prefix + "flow_stats_reply\n"
2994 outstr += prefix + "ofp header:\n"
2995 outstr += self.header.show(prefix + ' ')
2996 outstr += ofp_stats_reply.show(self)
2997 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
2998 for obj in self.stats:
2999 outstr += obj.show()
3000 return outstr
3001
3002 def __eq__(self, other):
3003 if type(self) != type(other): return False
3004 return (self.header == other.header and
3005 ofp_stats_reply.__eq__(self, other) and
3006 self.stats == other.stats)
3007
3008 def __ne__(self, other): return not self.__eq__(other)
3009
3010
3011class port_stats_request(ofp_stats_request, ofp_port_stats_request):
3012 """
3013 Wrapper class for port stats request message
3014 """
3015 def __init__(self, **kwargs):
3016 self.header = ofp_header()
3017 ofp_stats_request.__init__(self)
3018 ofp_port_stats_request.__init__(self)
3019 self.header.type = OFPT_STATS_REQUEST
3020 self.type = OFPST_PORT
3021 for (k, v) in kwargs.items():
3022 if hasattr(self, k):
3023 setattr(self, k, v)
3024 else:
3025 raise NameError("field %s does not exist in %s" % (k, self.__class__))
3026
3027 def pack(self, assertstruct=True):
3028 self.header.length = len(self)
3029 packed = self.header.pack()
3030 packed += ofp_stats_request.pack(self)
3031 packed += ofp_port_stats_request.pack(self)
3032 return packed
3033
3034 def unpack(self, binary_string):
3035 binary_string = self.header.unpack(binary_string)
3036 binary_string = ofp_stats_request.unpack(self, binary_string)
3037 binary_string = ofp_port_stats_request.unpack(self, binary_string)
3038 if len(binary_string) != 0:
3039 print "ERROR unpacking port: extra data"
3040 return binary_string
3041
3042 def __len__(self):
3043 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3044 OFP_PORT_STATS_REQUEST_BYTES
3045
3046 def show(self, prefix=''):
3047 outstr = prefix + "port_stats_request\n"
3048 outstr += prefix + "ofp header:\n"
3049 outstr += self.header.show(prefix + ' ')
3050 outstr += ofp_stats_request.show(self)
3051 outstr += ofp_port_stats_request.show(self)
3052 return outstr
3053
3054 def __eq__(self, other):
3055 if type(self) != type(other): return False
3056 return (self.header == other.header and
3057 ofp_stats_request.__eq__(self, other) and
3058 ofp_port_stats_request.__eq__(self, other))
3059
3060 def __ne__(self, other): return not self.__eq__(other)
3061
3062
3063class port_stats_reply(ofp_stats_reply):
3064 """
3065 Wrapper class for port stats reply
3066 """
3067 def __init__(self):
3068 self.header = ofp_header()
3069 ofp_stats_reply.__init__(self)
3070 self.header.type = OFPT_STATS_REPLY
3071 self.type = OFPST_PORT
3072 # stats: Array of type port_stats_entry
3073 self.stats = []
3074
3075 def pack(self, assertstruct=True):
3076 self.header.length = len(self)
3077 packed = self.header.pack()
3078 packed += ofp_stats_reply.pack(self)
3079 for obj in self.stats:
3080 packed += obj.pack()
3081 return packed
3082
3083 def unpack(self, binary_string):
3084 binary_string = self.header.unpack(binary_string)
3085 binary_string = ofp_stats_reply.unpack(self, binary_string)
3086 dummy = port_stats_entry()
3087 while len(binary_string) >= len(dummy):
3088 obj = port_stats_entry()
3089 binary_string = obj.unpack(binary_string)
3090 self.stats.append(obj)
3091 if len(binary_string) != 0:
3092 print "ERROR unpacking port stats string: extra bytes"
3093 return binary_string
3094
3095 def __len__(self):
3096 length = len(self.header) + OFP_STATS_REPLY_BYTES
3097 for obj in self.stats:
3098 length += len(obj)
3099 return length
3100
3101 def show(self, prefix=''):
3102 outstr = prefix + "port_stats_reply\n"
3103 outstr += prefix + "ofp header:\n"
3104 outstr += self.header.show(prefix + ' ')
3105 outstr += ofp_stats_reply.show(self)
3106 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3107 for obj in self.stats:
3108 outstr += obj.show()
3109 return outstr
3110
3111 def __eq__(self, other):
3112 if type(self) != type(other): return False
3113 return (self.header == other.header and
3114 ofp_stats_reply.__eq__(self, other) and
3115 self.stats == other.stats)
3116
3117 def __ne__(self, other): return not self.__eq__(other)
3118
3119
3120class queue_stats_request(ofp_stats_request, ofp_queue_stats_request):
3121 """
3122 Wrapper class for queue stats request message
3123 """
3124 def __init__(self, **kwargs):
3125 self.header = ofp_header()
3126 ofp_stats_request.__init__(self)
3127 ofp_queue_stats_request.__init__(self)
3128 self.header.type = OFPT_STATS_REQUEST
3129 self.type = OFPST_QUEUE
3130 for (k, v) in kwargs.items():
3131 if hasattr(self, k):
3132 setattr(self, k, v)
3133 else:
3134 raise NameError("field %s does not exist in %s" % (k, self.__class__))
3135
3136 def pack(self, assertstruct=True):
3137 self.header.length = len(self)
3138 packed = self.header.pack()
3139 packed += ofp_stats_request.pack(self)
3140 packed += ofp_queue_stats_request.pack(self)
3141 return packed
3142
3143 def unpack(self, binary_string):
3144 binary_string = self.header.unpack(binary_string)
3145 binary_string = ofp_stats_request.unpack(self, binary_string)
3146 binary_string = ofp_queue_stats_request.unpack(self, binary_string)
3147 if len(binary_string) != 0:
3148 print "ERROR unpacking queue: extra data"
3149 return binary_string
3150
3151 def __len__(self):
3152 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3153 OFP_QUEUE_STATS_REQUEST_BYTES
3154
3155 def show(self, prefix=''):
3156 outstr = prefix + "queue_stats_request\n"
3157 outstr += prefix + "ofp header:\n"
3158 outstr += self.header.show(prefix + ' ')
3159 outstr += ofp_stats_request.show(self)
3160 outstr += ofp_queue_stats_request.show(self)
3161 return outstr
3162
3163 def __eq__(self, other):
3164 if type(self) != type(other): return False
3165 return (self.header == other.header and
3166 ofp_stats_request.__eq__(self, other) and
3167 ofp_queue_stats_request.__eq__(self, other))
3168
3169 def __ne__(self, other): return not self.__eq__(other)
3170
3171
3172class queue_stats_reply(ofp_stats_reply):
3173 """
3174 Wrapper class for queue stats reply
3175 """
3176 def __init__(self):
3177 self.header = ofp_header()
3178 ofp_stats_reply.__init__(self)
3179 self.header.type = OFPT_STATS_REPLY
3180 self.type = OFPST_QUEUE
3181 # stats: Array of type queue_stats_entry
3182 self.stats = []
3183
3184 def pack(self, assertstruct=True):
3185 self.header.length = len(self)
3186 packed = self.header.pack()
3187 packed += ofp_stats_reply.pack(self)
3188 for obj in self.stats:
3189 packed += obj.pack()
3190 return packed
3191
3192 def unpack(self, binary_string):
3193 binary_string = self.header.unpack(binary_string)
3194 binary_string = ofp_stats_reply.unpack(self, binary_string)
3195 dummy = queue_stats_entry()
3196 while len(binary_string) >= len(dummy):
3197 obj = queue_stats_entry()
3198 binary_string = obj.unpack(binary_string)
3199 self.stats.append(obj)
3200 if len(binary_string) != 0:
3201 print "ERROR unpacking queue stats string: extra bytes"
3202 return binary_string
3203
3204 def __len__(self):
3205 length = len(self.header) + OFP_STATS_REPLY_BYTES
3206 for obj in self.stats:
3207 length += len(obj)
3208 return length
3209
3210 def show(self, prefix=''):
3211 outstr = prefix + "queue_stats_reply\n"
3212 outstr += prefix + "ofp header:\n"
3213 outstr += self.header.show(prefix + ' ')
3214 outstr += ofp_stats_reply.show(self)
3215 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3216 for obj in self.stats:
3217 outstr += obj.show()
3218 return outstr
3219
3220 def __eq__(self, other):
3221 if type(self) != type(other): return False
3222 return (self.header == other.header and
3223 ofp_stats_reply.__eq__(self, other) and
3224 self.stats == other.stats)
3225
3226 def __ne__(self, other): return not self.__eq__(other)
3227
3228
3229class table_stats_request(ofp_stats_request, ofp_table_stats_request):
3230 """
3231 Wrapper class for table stats request message
3232 """
3233 def __init__(self, **kwargs):
3234 self.header = ofp_header()
3235 ofp_stats_request.__init__(self)
3236 ofp_table_stats_request.__init__(self)
3237 self.header.type = OFPT_STATS_REQUEST
3238 self.type = OFPST_TABLE
3239 for (k, v) in kwargs.items():
3240 if hasattr(self, k):
3241 setattr(self, k, v)
3242 else:
3243 raise NameError("field %s does not exist in %s" % (k, self.__class__))
3244
3245 def pack(self, assertstruct=True):
3246 self.header.length = len(self)
3247 packed = self.header.pack()
3248 packed += ofp_stats_request.pack(self)
3249 packed += ofp_table_stats_request.pack(self)
3250 return packed
3251
3252 def unpack(self, binary_string):
3253 binary_string = self.header.unpack(binary_string)
3254 binary_string = ofp_stats_request.unpack(self, binary_string)
3255 binary_string = ofp_table_stats_request.unpack(self, binary_string)
3256 if len(binary_string) != 0:
3257 print "ERROR unpacking table: extra data"
3258 return binary_string
3259
3260 def __len__(self):
3261 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3262 OFP_TABLE_STATS_REQUEST_BYTES
3263
3264 def show(self, prefix=''):
3265 outstr = prefix + "table_stats_request\n"
3266 outstr += prefix + "ofp header:\n"
3267 outstr += self.header.show(prefix + ' ')
3268 outstr += ofp_stats_request.show(self)
3269 outstr += ofp_table_stats_request.show(self)
3270 return outstr
3271
3272 def __eq__(self, other):
3273 if type(self) != type(other): return False
3274 return (self.header == other.header and
3275 ofp_stats_request.__eq__(self, other) and
3276 ofp_table_stats_request.__eq__(self, other))
3277
3278 def __ne__(self, other): return not self.__eq__(other)
3279
3280
3281class table_stats_reply(ofp_stats_reply):
3282 """
3283 Wrapper class for table stats reply
3284 """
3285 def __init__(self):
3286 self.header = ofp_header()
3287 ofp_stats_reply.__init__(self)
3288 self.header.type = OFPT_STATS_REPLY
3289 self.type = OFPST_TABLE
3290 # stats: Array of type table_stats_entry
3291 self.stats = []
3292
3293 def pack(self, assertstruct=True):
3294 self.header.length = len(self)
3295 packed = self.header.pack()
3296 packed += ofp_stats_reply.pack(self)
3297 for obj in self.stats:
3298 packed += obj.pack()
3299 return packed
3300
3301 def unpack(self, binary_string):
3302 binary_string = self.header.unpack(binary_string)
3303 binary_string = ofp_stats_reply.unpack(self, binary_string)
3304 dummy = table_stats_entry()
3305 while len(binary_string) >= len(dummy):
3306 obj = table_stats_entry()
3307 binary_string = obj.unpack(binary_string)
3308 self.stats.append(obj)
3309 if len(binary_string) != 0:
3310 print "ERROR unpacking table stats string: extra bytes"
3311 return binary_string
3312
3313 def __len__(self):
3314 length = len(self.header) + OFP_STATS_REPLY_BYTES
3315 for obj in self.stats:
3316 length += len(obj)
3317 return length
3318
3319 def show(self, prefix=''):
3320 outstr = prefix + "table_stats_reply\n"
3321 outstr += prefix + "ofp header:\n"
3322 outstr += self.header.show(prefix + ' ')
3323 outstr += ofp_stats_reply.show(self)
3324 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3325 for obj in self.stats:
3326 outstr += obj.show()
3327 return outstr
3328
3329 def __eq__(self, other):
3330 if type(self) != type(other): return False
3331 return (self.header == other.header and
3332 ofp_stats_reply.__eq__(self, other) and
3333 self.stats == other.stats)
3334
3335 def __ne__(self, other): return not self.__eq__(other)
3336
3337
3338message_type_list = (
3339 aggregate_stats_reply,
3340 aggregate_stats_request,
3341 bad_action_error_msg,
3342 bad_request_error_msg,
3343 barrier_reply,
3344 barrier_request,
3345 desc_stats_reply,
3346 desc_stats_request,
3347 echo_reply,
3348 echo_request,
3349 features_reply,
3350 features_request,
3351 flow_mod,
3352 flow_mod_failed_error_msg,
3353 flow_removed,
3354 flow_stats_reply,
3355 flow_stats_request,
3356 get_config_reply,
3357 get_config_request,
3358 hello,
3359 hello_failed_error_msg,
3360 packet_in,
3361 packet_out,
3362 port_mod,
3363 port_mod_failed_error_msg,
3364 port_stats_reply,
3365 port_stats_request,
3366 port_status,
3367 queue_get_config_reply,
3368 queue_get_config_request,
3369 queue_op_failed_error_msg,
3370 queue_stats_reply,
3371 queue_stats_request,
3372 set_config,
3373 table_stats_reply,
3374 table_stats_request,
3375 vendor
3376 )
3377