1 | """Helper python-openflow functions.""" |
||
2 | |||
3 | # System imports |
||
4 | |||
5 | # Third-party imports |
||
6 | |||
7 | # Local source tree imports |
||
8 | # Importing asynchronous messages |
||
9 | 1 | from pyof.v0x04.asynchronous.error_msg import ErrorMsg |
|
10 | 1 | from pyof.v0x04.asynchronous.flow_removed import FlowRemoved |
|
11 | 1 | from pyof.v0x04.asynchronous.packet_in import PacketIn |
|
12 | 1 | from pyof.v0x04.asynchronous.port_status import PortStatus |
|
13 | # Importing controller2switch messages |
||
14 | 1 | from pyof.v0x04.common.header import Header, Type |
|
15 | 1 | from pyof.v0x04.controller2switch.barrier_reply import BarrierReply |
|
16 | 1 | from pyof.v0x04.controller2switch.barrier_request import BarrierRequest |
|
17 | 1 | from pyof.v0x04.controller2switch.features_reply import FeaturesReply |
|
18 | 1 | from pyof.v0x04.controller2switch.features_request import FeaturesRequest |
|
19 | 1 | from pyof.v0x04.controller2switch.flow_mod import FlowMod |
|
20 | 1 | from pyof.v0x04.controller2switch.get_async_reply import GetAsyncReply |
|
21 | 1 | from pyof.v0x04.controller2switch.get_async_request import GetAsyncRequest |
|
22 | 1 | from pyof.v0x04.controller2switch.get_config_reply import GetConfigReply |
|
23 | 1 | from pyof.v0x04.controller2switch.get_config_request import GetConfigRequest |
|
24 | 1 | from pyof.v0x04.controller2switch.group_mod import GroupMod |
|
25 | 1 | from pyof.v0x04.controller2switch.meter_mod import MeterMod |
|
26 | 1 | from pyof.v0x04.controller2switch.multipart_reply import MultipartReply |
|
27 | 1 | from pyof.v0x04.controller2switch.multipart_request import MultipartRequest |
|
28 | 1 | from pyof.v0x04.controller2switch.packet_out import PacketOut |
|
29 | 1 | from pyof.v0x04.controller2switch.port_mod import PortMod |
|
30 | 1 | from pyof.v0x04.controller2switch.queue_get_config_reply import ( |
|
31 | QueueGetConfigReply) |
||
32 | 1 | from pyof.v0x04.controller2switch.queue_get_config_request import ( |
|
33 | QueueGetConfigRequest) |
||
34 | 1 | from pyof.v0x04.controller2switch.role_reply import RoleReply |
|
35 | 1 | from pyof.v0x04.controller2switch.role_request import RoleRequest |
|
36 | 1 | from pyof.v0x04.controller2switch.set_async import SetAsync |
|
37 | 1 | from pyof.v0x04.controller2switch.set_config import SetConfig |
|
38 | 1 | from pyof.v0x04.controller2switch.table_mod import TableMod |
|
39 | # Importing symmetric messages |
||
40 | 1 | from pyof.v0x04.symmetric.echo_reply import EchoReply |
|
41 | 1 | from pyof.v0x04.symmetric.echo_request import EchoRequest |
|
42 | 1 | from pyof.v0x04.symmetric.experimenter import ExperimenterHeader |
|
43 | 1 | from pyof.v0x04.symmetric.hello import Hello |
|
44 | |||
45 | 1 | __all__ = ('MESSAGE_TYPES', 'new_message_from_header', |
|
46 | 'new_message_from_message_type', 'unpack_message') |
||
47 | |||
48 | 1 | MESSAGE_TYPES = { |
|
49 | |||
50 | # Symetric/Immutable messages |
||
51 | str(Type.OFPT_HELLO): Hello, |
||
52 | str(Type.OFPT_ERROR): ErrorMsg, |
||
53 | str(Type.OFPT_ECHO_REQUEST): EchoRequest, |
||
54 | str(Type.OFPT_ECHO_REPLY): EchoReply, |
||
55 | str(Type.OFPT_EXPERIMENTER): ExperimenterHeader, |
||
56 | |||
57 | # Switch configuration messages |
||
58 | # Controller/Switch messages |
||
59 | str(Type.OFPT_FEATURES_REQUEST): FeaturesRequest, |
||
60 | str(Type.OFPT_FEATURES_REPLY): FeaturesReply, |
||
61 | str(Type.OFPT_GET_CONFIG_REQUEST): GetConfigRequest, |
||
62 | str(Type.OFPT_GET_CONFIG_REPLY): GetConfigReply, |
||
63 | str(Type.OFPT_SET_CONFIG): SetConfig, |
||
64 | |||
65 | # Async messages |
||
66 | str(Type.OFPT_PACKET_IN): PacketIn, |
||
67 | str(Type.OFPT_FLOW_REMOVED): FlowRemoved, |
||
68 | str(Type.OFPT_PORT_STATUS): PortStatus, |
||
69 | |||
70 | # Controller command messages |
||
71 | # Controller/Switch message |
||
72 | str(Type.OFPT_PACKET_OUT): PacketOut, |
||
73 | str(Type.OFPT_FLOW_MOD): FlowMod, |
||
74 | str(Type.OFPT_GROUP_MOD): GroupMod, |
||
75 | str(Type.OFPT_PORT_MOD): PortMod, |
||
76 | str(Type.OFPT_TABLE_MOD): TableMod, |
||
77 | |||
78 | # Multipart messages. |
||
79 | # Controller/Switch message |
||
80 | str(Type.OFPT_MULTIPART_REPLY): MultipartReply, |
||
81 | str(Type.OFPT_MULTIPART_REQUEST): MultipartRequest, |
||
82 | |||
83 | # Barrier messages |
||
84 | # Controller/Switch message |
||
85 | str(Type.OFPT_BARRIER_REQUEST): BarrierRequest, |
||
86 | str(Type.OFPT_BARRIER_REPLY): BarrierReply, |
||
87 | |||
88 | # Queue Configuration messages |
||
89 | # Controller/Switch message |
||
90 | str(Type.OFPT_QUEUE_GET_CONFIG_REQUEST): QueueGetConfigRequest, |
||
91 | str(Type.OFPT_QUEUE_GET_CONFIG_REPLY): QueueGetConfigReply, |
||
92 | |||
93 | # Controller role change request message |
||
94 | # Controller/Switch message |
||
95 | str(Type.OFPT_ROLE_REQUEST): RoleRequest, |
||
96 | str(Type.OFPT_ROLE_REPLY): RoleReply, |
||
97 | |||
98 | # Asynchronous message configuration |
||
99 | # Controller/Switch message |
||
100 | str(Type.OFPT_GET_ASYNC_REQUEST): GetAsyncRequest, |
||
101 | str(Type.OFPT_GET_ASYNC_REPLY): GetAsyncReply, |
||
102 | str(Type.OFPT_SET_ASYNC): SetAsync, |
||
103 | |||
104 | # Meters and rate limiters configuration messages |
||
105 | # Controller/Switch message |
||
106 | str(Type.OFPT_METER_MOD): MeterMod, |
||
107 | } |
||
108 | |||
109 | |||
110 | 1 | def new_message_from_message_type(message_type): |
|
111 | """Given an OpenFlow Message Type, return an empty message of that type. |
||
112 | |||
113 | Args: |
||
114 | messageType (:class:`~pyof.v0x04.common.header.Type`): |
||
115 | Python-openflow message. |
||
116 | |||
117 | Returns: |
||
118 | Empty OpenFlow message of the requested message type. |
||
119 | |||
120 | Raises: |
||
121 | KytosUndefinedMessageType: Unkown Message_Type. |
||
122 | |||
123 | """ |
||
124 | 1 | message_type = str(message_type) |
|
125 | 1 | if message_type not in MESSAGE_TYPES: |
|
126 | msg = "Define class for {} in {}".format(message_type, __file__) |
||
127 | raise ValueError(msg) |
||
128 | |||
129 | 1 | message_class = MESSAGE_TYPES.get(message_type) |
|
130 | 1 | message_instance = message_class() |
|
131 | |||
132 | 1 | return message_instance |
|
133 | |||
134 | |||
135 | 1 | View Code Duplication | def new_message_from_header(header): |
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
136 | """Given an OF Header, return an empty message of header's message_type. |
||
137 | |||
138 | Args: |
||
139 | header (:class:`~pyof.v0x04.common.header.Header`): |
||
140 | Unpacked OpenFlow Header. |
||
141 | |||
142 | Returns: |
||
143 | Empty OpenFlow message of the same type of message_type attribute from |
||
144 | the given header. |
||
145 | The header attribute of the message will be populated. |
||
146 | |||
147 | Raises: |
||
148 | KytosUndefinedMessageType: Unkown Message_Type. |
||
149 | |||
150 | """ |
||
151 | 1 | message_type = header.message_type |
|
152 | 1 | if not isinstance(message_type, Type): |
|
153 | 1 | try: |
|
154 | 1 | if isinstance(message_type, str): |
|
155 | message_type = Type[message_type] |
||
156 | 1 | elif isinstance(message_type, int): |
|
157 | message_type = Type(message_type) |
||
158 | except ValueError: |
||
159 | raise ValueError |
||
160 | |||
161 | 1 | message = new_message_from_message_type(message_type) |
|
162 | 1 | message.header.xid = header.xid |
|
163 | 1 | message.header.length = header.length |
|
164 | |||
165 | 1 | return message |
|
166 | |||
167 | |||
168 | 1 | View Code Duplication | def unpack_message(buffer): |
0 ignored issues
–
show
|
|||
169 | """Unpack the whole buffer, including header pack. |
||
170 | |||
171 | Args: |
||
172 | buffer (bytes): Bytes representation of a openflow message. |
||
173 | |||
174 | Returns: |
||
175 | object: Instance of openflow message. |
||
176 | |||
177 | """ |
||
178 | 1 | hdr_size = Header().get_size() |
|
179 | 1 | hdr_buff, msg_buff = buffer[:hdr_size], buffer[hdr_size:] |
|
180 | 1 | header = Header() |
|
181 | 1 | header.unpack(hdr_buff) |
|
182 | 1 | message = new_message_from_header(header) |
|
183 | 1 | message.unpack(msg_buff) |
|
184 | return message |
||
185 |