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