1# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
2# Copyright (C) 2012 Isaku Yamahata <yamahata at valinux co jp>
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#    http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13# implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""
18OpenFlow 1.3 definitions.
19"""
20
21from ryu.lib import type_desc
22from ryu.ofproto import nicira_ext
23from ryu.ofproto import ofproto_utils
24from ryu.ofproto import oxm_fields
25
26from struct import calcsize
27
28# struct ofp_header
29OFP_HEADER_PACK_STR = '!BBHI'
30OFP_HEADER_SIZE = 8
31assert calcsize(OFP_HEADER_PACK_STR) == OFP_HEADER_SIZE
32
33# enum ofp_type
34OFPT_HELLO = 0                      # Symmetric message
35OFPT_ERROR = 1                      # Symmetric message
36OFPT_ECHO_REQUEST = 2               # Symmetric message
37OFPT_ECHO_REPLY = 3                 # Symmetric message
38OFPT_EXPERIMENTER = 4               # Symmetric message
39
40OFPT_FEATURES_REQUEST = 5           # Controller/switch message
41OFPT_FEATURES_REPLY = 6             # Controller/switch message
42OFPT_GET_CONFIG_REQUEST = 7         # Controller/switch message
43OFPT_GET_CONFIG_REPLY = 8           # Controller/switch message
44OFPT_SET_CONFIG = 9                 # Controller/switch message
45
46OFPT_PACKET_IN = 10                 # Async message
47OFPT_FLOW_REMOVED = 11              # Async message
48OFPT_PORT_STATUS = 12               # Async message
49
50OFPT_PACKET_OUT = 13                # Controller/switch message
51OFPT_FLOW_MOD = 14                  # Controller/switch message
52OFPT_GROUP_MOD = 15                 # Controller/switch message
53OFPT_PORT_MOD = 16                  # Controller/switch message
54OFPT_TABLE_MOD = 17                 # Controller/switch message
55
56OFPT_MULTIPART_REQUEST = 18         # Controller/switch message
57OFPT_MULTIPART_REPLY = 19           # Controller/switch message
58
59OFPT_BARRIER_REQUEST = 20           # Controller/switch message
60OFPT_BARRIER_REPLY = 21             # Controller/switch message
61OFPT_QUEUE_GET_CONFIG_REQUEST = 22  # Controller/switch message
62OFPT_QUEUE_GET_CONFIG_REPLY = 23    # Controller/switch message
63
64OFPT_ROLE_REQUEST = 24              # Controller/switch message
65OFPT_ROLE_REPLY = 25                # Controller/switch message
66
67OFPT_GET_ASYNC_REQUEST = 26         # Controller/switch message
68OFPT_GET_ASYNC_REPLY = 27           # Controller/switch message
69OFPT_SET_ASYNC = 28                 # Controller/switch message
70
71OFPT_METER_MOD = 29                 # Controller/switch message
72
73# struct ofp_port
74OFP_MAX_PORT_NAME_LEN = 16
75OFP_ETH_ALEN = 6
76OFP_ETH_ALEN_STR = str(OFP_ETH_ALEN)
77_OFP_PORT_PACK_STR = 'I4x' + OFP_ETH_ALEN_STR + 's' + '2x' + \
78                     str(OFP_MAX_PORT_NAME_LEN) + 's' + 'IIIIIIII'
79OFP_PORT_PACK_STR = '!' + _OFP_PORT_PACK_STR
80OFP_PORT_SIZE = 64
81assert calcsize(OFP_PORT_PACK_STR) == OFP_PORT_SIZE
82
83# enum ofp_port_config
84OFPPC_PORT_DOWN = 1 << 0        # Port is administratively down.
85OFPPC_NO_RECV = 1 << 2          # Drop all packets recieved by port.
86OFPPC_NO_FWD = 1 << 5           # Drop packets forwarded to port.
87OFPPC_NO_PACKET_IN = 1 << 6     # Do not send packet-in msgs for port.
88
89# enum ofp_port_state
90OFPPS_LINK_DOWN = 1 << 0        # No physical link present.
91OFPPS_BLOCKED = 1 << 1          # Port is blocked.
92OFPPS_LIVE = 1 << 2             # Live for Fast Failover Group.
93
94# enum ofp_port_no
95OFPP_MAX = 0xffffff00
96OFPP_IN_PORT = 0xfffffff8       # Send the packet out the input port. This
97                                # virtual port must be explicitly used
98                                # in order to send back out of the input
99                                # port.
100OFPP_TABLE = 0xfffffff9         # Perform actions in flow table.
101                                # NB: This can only be the destination
102                                # port for packet-out messages.
103OFPP_NORMAL = 0xfffffffa        # Process with normal L2/L3 switching.
104OFPP_FLOOD = 0xfffffffb         # All physical ports except input port and
105                                # those disabled by STP.
106OFPP_ALL = 0xfffffffc           # All physical ports except input port.
107OFPP_CONTROLLER = 0xfffffffd    # Send to controller.
108OFPP_LOCAL = 0xfffffffe         # Local openflow "port".
109OFPP_ANY = 0xffffffff 	        # Not associated with a physical port.
110
111# All ones is used to indicate all queues in a port (for stats retrieval).
112OFPQ_ALL = 0xffffffff
113
114# enum ofp_port_features
115OFPPF_10MB_HD = 1 << 0          # 10 Mb half-duplex rate support.
116OFPPF_10MB_FD = 1 << 1          # 10 Mb full-duplex rate support.
117OFPPF_100MB_HD = 1 << 2         # 100 Mb half-duplex rate support.
118OFPPF_100MB_FD = 1 << 3         # 100 Mb full-duplex rate support.
119OFPPF_1GB_HD = 1 << 4           # 1 Gb half-duplex rate support.
120OFPPF_1GB_FD = 1 << 5           # 1 Gb full-duplex rate support.
121OFPPF_10GB_FD = 1 << 6          # 10 Gb full-duplex rate support.
122OFPPF_40GB_FD = 1 << 7          # 40 Gb full-duplex rate support.
123OFPPF_100GB_FD = 1 << 8         # 100 Gb full-duplex rate support.
124OFPPF_1TB_FD = 1 << 9           # 1 Tb full-duplex rate support.
125OFPPF_OTHER = 1 << 10           # Other rate, not in the list.
126OFPPF_COPPER = 1 << 11          # Copper medium.
127OFPPF_FIBER = 1 << 12           # Fiber medium.
128OFPPF_AUTONEG = 1 << 13         # Auto-negotiation.
129OFPPF_PAUSE = 1 << 14           # Pause.
130OFPPF_PAUSE_ASYM = 1 << 15      # Asymmetric pause.
131
132# struct ofp_packet_queue
133OFP_PACKET_QUEUE_PACK_STR = '!IIH6x'
134OFP_PACKET_QUEUE_SIZE = 16
135assert calcsize(OFP_PACKET_QUEUE_PACK_STR) == OFP_PACKET_QUEUE_SIZE
136
137# enum ofp_queue_properties
138OFPQT_MIN_RATE = 1              # Minimum datarate guaranteed.
139OFPQT_MAX_RATE = 2              # Maximum datarate.
140OFPQT_EXPERIMENTER = 0xffff     # Experimenter defined property.
141
142# struct ofp_queue_prop_header
143OFP_QUEUE_PROP_HEADER_PACK_STR = '!HH4x'
144OFP_QUEUE_PROP_HEADER_SIZE = 8
145assert calcsize(OFP_QUEUE_PROP_HEADER_PACK_STR) == OFP_QUEUE_PROP_HEADER_SIZE
146
147# struct ofp_queue_prop_min_rate
148OFP_QUEUE_PROP_MIN_RATE_PACK_STR = '!H6x'
149OFP_QUEUE_PROP_MIN_RATE_SIZE = 16
150assert (calcsize(OFP_QUEUE_PROP_MIN_RATE_PACK_STR) +
151        OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_MIN_RATE_SIZE
152
153# struct ofp_queue_prop_max_rate
154OFP_QUEUE_PROP_MAX_RATE_PACK_STR = '!H6x'
155OFP_QUEUE_PROP_MAX_RATE_SIZE = 16
156assert (calcsize(OFP_QUEUE_PROP_MAX_RATE_PACK_STR) +
157        OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_MAX_RATE_SIZE
158
159# struct ofp_queue_prop_experimenter
160OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR = '!I4x'
161OFP_QUEUE_PROP_EXPERIMENTER_SIZE = 16
162assert (calcsize(OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR) +
163        OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_EXPERIMENTER_SIZE
164
165# struct ofp_match
166_OFP_MATCH_PACK_STR = 'HHBBBB'
167OFP_MATCH_PACK_STR = '!' + _OFP_MATCH_PACK_STR
168OFP_MATCH_SIZE = 8
169assert calcsize(OFP_MATCH_PACK_STR) == OFP_MATCH_SIZE
170
171# enum ofp_match_type
172OFPMT_STANDARD = 0  # Deprecated
173OFPMT_OXM = 1       # OpenFlow Extensible Match
174
175# enum ofp_oxm_class
176OFPXMC_NXM_0 = 0x0000           # Backward compatibility with NXM
177OFPXMC_NXM_1 = 0x0001           # Backward compatibility with NXM
178OFPXMC_OPENFLOW_BASIC = 0x8000  # Basic class for OpenFlow
179OFPXMC_EXPERIMENTER = 0xFFFF    # Experimenter class
180
181# enum ofp_vlan_id
182OFPVID_PRESENT = 0x1000     # bit that indicate that a VLAN id is set.
183OFPVID_NONE = 0x0000        # No VLAN id was set.
184
185# enum ofp_ipv6exthdr_flags
186OFPIEH_NONEXT = 1 << 0      # "No next header" encountered.
187OFPIEH_ESP = 1 << 1         # Encrypted Sec Payload header present.
188OFPIEH_AUTH = 1 << 2        # Authentication header present.
189OFPIEH_DEST = 1 << 3        # 1 or 2 dest headers present.
190OFPIEH_FRAG = 1 << 4        # Fragment header present.
191OFPIEH_ROUTER = 1 << 5      # Router header present.
192OFPIEH_HOP = 1 << 6         # Hop-by-hop header present.
193OFPIEH_UNREP = 1 << 7       # Unexpected repeats encountered.
194OFPIEH_UNSEQ = 1 << 8       # Unexpected sequencing encountered.
195
196# ofp_oxm_experimenter_header
197OFP_OXM_EXPERIMENTER_HEADER_PACK_STR = '!II'
198OFP_OXM_EXPERIMENTER_HEADER_SIZE = 8
199assert (calcsize(OFP_OXM_EXPERIMENTER_HEADER_PACK_STR) ==
200        OFP_OXM_EXPERIMENTER_HEADER_SIZE)
201
202# enum ofp_instruction_type
203OFPIT_GOTO_TABLE = 1            # Setup the next table in the lookup pipeline.
204OFPIT_WRITE_METADATA = 2        # Setup the metadata field for use later in
205                                # pipeline.
206OFPIT_WRITE_ACTIONS = 3         # Write the action(s) onto the datapath
207                                # action set
208OFPIT_APPLY_ACTIONS = 4         # Applies the action(s) immediately
209OFPIT_CLEAR_ACTIONS = 5         # Clears all actions from the datapath action
210                                # set
211OFPIT_METER = 6                 # Apply meter (rate limiter)
212OFPIT_EXPERIMENTER = 0xFFFF     # Experimenter instruction
213
214# struct ofp_instruction_goto_table
215OFP_INSTRUCTION_GOTO_TABLE_PACK_STR = '!HHB3x'
216OFP_INSTRUCTION_GOTO_TABLE_SIZE = 8
217assert (calcsize(OFP_INSTRUCTION_GOTO_TABLE_PACK_STR) ==
218        OFP_INSTRUCTION_GOTO_TABLE_SIZE)
219
220# struct ofp_instruction_write_metadata
221OFP_INSTRUCTION_WRITE_METADATA_PACK_STR = '!HH4xQQ'
222OFP_INSTRUCTION_WRITE_METADATA_SIZE = 24
223assert (calcsize(OFP_INSTRUCTION_WRITE_METADATA_PACK_STR) ==
224        OFP_INSTRUCTION_WRITE_METADATA_SIZE)
225
226# struct ofp_instruction_actions
227OFP_INSTRUCTION_ACTIONS_PACK_STR = '!HH4x'
228OFP_INSTRUCTION_ACTIONS_SIZE = 8
229assert (calcsize(OFP_INSTRUCTION_ACTIONS_PACK_STR) ==
230        OFP_INSTRUCTION_ACTIONS_SIZE)
231
232# struct ofp_instruction_meter
233OFP_INSTRUCTION_METER_PACK_STR = '!HHI'
234OFP_INSTRUCTION_METER_SIZE = 8
235assert calcsize(OFP_INSTRUCTION_METER_PACK_STR) == OFP_INSTRUCTION_METER_SIZE
236
237# enum ofp_action_type
238OFPAT_OUTPUT = 0                # Output to switch port.
239OFPAT_COPY_TTL_OUT = 11         # Copy TTL "outwards" -- from
240                                # next-to-outermost to outermost
241OFPAT_COPY_TTL_IN = 12          # Copy TTL "inwards" -- from outermost to
242                                # next-to-outermost
243OFPAT_SET_MPLS_TTL = 15         # MPLS TTL.
244OFPAT_DEC_MPLS_TTL = 16         # Decrement MPLS TTL
245OFPAT_PUSH_VLAN = 17            # Push a new VLAN tag
246OFPAT_POP_VLAN = 18             # Pop the outer VLAN tag
247OFPAT_PUSH_MPLS = 19            # Push a new MPLS tag
248OFPAT_POP_MPLS = 20             # Pop the outer MPLS tag
249OFPAT_SET_QUEUE = 21            # Set queue id when outputting to a port
250OFPAT_GROUP = 22                # Apply group
251OFPAT_SET_NW_TTL = 23           # IP TTL.
252OFPAT_DEC_NW_TTL = 24           # Decrement IP TTL.
253OFPAT_SET_FIELD = 25            # Set a header field using OXM TLV format.
254OFPAT_PUSH_PBB = 26             # Push a new PBB service tag (I-TAG)
255OFPAT_POP_PBB = 27              # Pop the outer PBB service tag (I-TAG)
256OFPAT_EXPERIMENTER = 0xffff
257
258# struct ofp_action_header
259OFP_ACTION_HEADER_PACK_STR = '!HH4x'
260OFP_ACTION_HEADER_SIZE = 8
261assert calcsize(OFP_ACTION_HEADER_PACK_STR) == OFP_ACTION_HEADER_SIZE
262
263# struct ofp_action_output
264OFP_ACTION_OUTPUT_PACK_STR = '!HHIH6x'
265OFP_ACTION_OUTPUT_SIZE = 16
266assert calcsize(OFP_ACTION_OUTPUT_PACK_STR) == OFP_ACTION_OUTPUT_SIZE
267
268# enum ofp_controller_max_len
269OFPCML_MAX = 0xffe5         # maximum max_len value which can be used to
270                            # request a specific byte length.
271OFPCML_NO_BUFFER = 0xffff   # indicates that no buffering should be
272                            # applied and the whole packet is to be
273                            # sent to the controller.
274
275# struct ofp_action_group
276OFP_ACTION_GROUP_PACK_STR = '!HHI'
277OFP_ACTION_GROUP_SIZE = 8
278assert calcsize(OFP_ACTION_GROUP_PACK_STR) == OFP_ACTION_GROUP_SIZE
279
280# struct ofp_action_set_queue
281OFP_ACTION_SET_QUEUE_PACK_STR = '!HHI'
282OFP_ACTION_SET_QUEUE_SIZE = 8
283assert calcsize(OFP_ACTION_SET_QUEUE_PACK_STR) == OFP_ACTION_SET_QUEUE_SIZE
284
285# struct ofp_action_mpls_ttl
286OFP_ACTION_MPLS_TTL_PACK_STR = '!HHB3x'
287OFP_ACTION_MPLS_TTL_SIZE = 8
288assert calcsize(OFP_ACTION_MPLS_TTL_PACK_STR) == OFP_ACTION_MPLS_TTL_SIZE
289
290# struct ofp_action_nw_ttl
291OFP_ACTION_NW_TTL_PACK_STR = '!HHB3x'
292OFP_ACTION_NW_TTL_SIZE = 8
293assert calcsize(OFP_ACTION_NW_TTL_PACK_STR) == OFP_ACTION_NW_TTL_SIZE
294
295# struct ofp_action_push
296OFP_ACTION_PUSH_PACK_STR = '!HHH2x'
297OFP_ACTION_PUSH_SIZE = 8
298assert calcsize(OFP_ACTION_PUSH_PACK_STR) == OFP_ACTION_PUSH_SIZE
299
300# struct ofp_action_pop_mpls
301OFP_ACTION_POP_MPLS_PACK_STR = '!HHH2x'
302OFP_ACTION_POP_MPLS_SIZE = 8
303assert calcsize(OFP_ACTION_POP_MPLS_PACK_STR) == OFP_ACTION_POP_MPLS_SIZE
304
305# struct ofp_action_set_field
306OFP_ACTION_SET_FIELD_PACK_STR = '!HH4x'
307OFP_ACTION_SET_FIELD_SIZE = 8
308assert calcsize(OFP_ACTION_SET_FIELD_PACK_STR) == OFP_ACTION_SET_FIELD_SIZE
309
310# struct ofp_action_experimenter_header
311OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR = '!HHI'
312OFP_ACTION_EXPERIMENTER_HEADER_SIZE = 8
313assert (calcsize(OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR) ==
314        OFP_ACTION_EXPERIMENTER_HEADER_SIZE)
315
316# ofp_switch_features
317OFP_SWITCH_FEATURES_PACK_STR = '!QIBB2xII'
318OFP_SWITCH_FEATURES_SIZE = 32
319assert (calcsize(OFP_SWITCH_FEATURES_PACK_STR) + OFP_HEADER_SIZE ==
320        OFP_SWITCH_FEATURES_SIZE)
321
322# enum ofp_capabilities
323OFPC_FLOW_STATS = 1 << 0    # Flow statistics.
324OFPC_TABLE_STATS = 1 << 1   # Table statistics.
325OFPC_PORT_STATS = 1 << 2    # Port statistics.
326OFPC_GROUP_STATS = 1 << 3   # Group statistics.
327OFPC_IP_REASM = 1 << 5      # Can reassemble IP fragments.
328OFPC_QUEUE_STATS = 1 << 6   # Queue statistics.
329OFPC_PORT_BLOCKED = 1 << 8  # Switch will block looping ports.
330
331# struct ofp_switch_config
332OFP_SWITCH_CONFIG_PACK_STR = '!HH'
333OFP_SWITCH_CONFIG_SIZE = 12
334assert (calcsize(OFP_SWITCH_CONFIG_PACK_STR) + OFP_HEADER_SIZE ==
335        OFP_SWITCH_CONFIG_SIZE)
336
337# enum ofp_config_flags
338OFPC_FRAG_NORMAL = 0    # No special handling for fragments.
339OFPC_FRAG_DROP = 1      # Drop fragments.
340OFPC_FRAG_REASM = 2     # Reassemble (only if OFPC_IP_REASM set).
341OFPC_FRAG_MASK = 3
342
343# enum ofp_table
344OFPTT_MAX = 0xfe
345OFPTT_ALL = 0xff
346
347# struct ofp_table_mod
348OFP_TABLE_MOD_PACK_STR = '!B3xI'
349OFP_TABLE_MOD_SIZE = 16
350assert (calcsize(OFP_TABLE_MOD_PACK_STR) + OFP_HEADER_SIZE ==
351        OFP_TABLE_MOD_SIZE)
352
353_OFP_FLOW_MOD_PACK_STR0 = 'QQBBHHHIIIH2x'
354OFP_FLOW_MOD_PACK_STR = '!' + _OFP_FLOW_MOD_PACK_STR0 + _OFP_MATCH_PACK_STR
355OFP_FLOW_MOD_PACK_STR0 = '!' + _OFP_FLOW_MOD_PACK_STR0
356OFP_FLOW_MOD_SIZE = 56
357assert (calcsize(OFP_FLOW_MOD_PACK_STR) + OFP_HEADER_SIZE ==
358        OFP_FLOW_MOD_SIZE)
359
360# enum ofp_flow_mod_command
361OFPFC_ADD = 0               # New flow.
362OFPFC_MODIFY = 1            # Modify all matching flows.
363OFPFC_MODIFY_STRICT = 2     # Modify entry strictly matching wildcards
364OFPFC_DELETE = 3            # Delete all matching flows.
365OFPFC_DELETE_STRICT = 4     # Strictly match wildcards and priority.
366
367# By default, choose a priority in the middle.
368OFP_DEFAULT_PRIORITY = 0x8000
369
370# enum ofp_flow_mod_flags
371OFPFF_SEND_FLOW_REM = 1 << 0    # Send flow removed message when flow
372                                # expires or is deleted.
373OFPFF_CHECK_OVERLAP = 1 << 1    # Check for overlapping entries first.
374OFPFF_RESET_COUNTS = 1 << 2     # Reset flow packet and byte counts.
375OFPFF_NO_PKT_COUNTS = 1 << 3    # Don't keep track of packet count.
376OFPFF_NO_BYT_COUNTS = 1 << 4    # Don't keep track of byte count.
377
378# struct ofp_group_mod
379OFP_GROUP_MOD_PACK_STR = '!HBxI'
380OFP_GROUP_MOD_SIZE = 16
381assert (calcsize(OFP_GROUP_MOD_PACK_STR) + OFP_HEADER_SIZE ==
382        OFP_GROUP_MOD_SIZE)
383
384# enum ofp_group_mod_command
385OFPGC_ADD = 0       # New group.
386OFPGC_MODIFY = 1    # Modify all matching groups.
387OFPGC_DELETE = 2    # Delete all matching groups.
388
389# enum ofp_group
390OFPG_MAX = 0xffffff00   # Last usable group number.
391# Fake groups
392OFPG_ALL = 0xfffffffc   # Represents all groups for group delete commands.
393OFPG_ANY = 0xffffffff   # Wildcard group used only for flow stats requests.
394                        # Selects all flows regardless of group
395                        # (including flows with no group).
396
397# enum ofp_group_type
398OFPGT_ALL = 0       # All (multicast/broadcast) group.
399OFPGT_SELECT = 1    # Select group.
400OFPGT_INDIRECT = 2  # Indirect group.
401OFPGT_FF = 3        # Fast failover group.
402
403# struct ofp_bucket
404OFP_BUCKET_PACK_STR = '!HHII4x'
405OFP_BUCKET_SIZE = 16
406assert calcsize(OFP_BUCKET_PACK_STR) == OFP_BUCKET_SIZE
407
408# struct ofp_port_mod
409OFP_PORT_MOD_PACK_STR = '!I4x' + OFP_ETH_ALEN_STR + 's2xIII4x'
410OFP_PORT_MOD_SIZE = 40
411assert (calcsize(OFP_PORT_MOD_PACK_STR) + OFP_HEADER_SIZE ==
412        OFP_PORT_MOD_SIZE)
413
414# struct ofp_meter_mod
415OFP_METER_MOD_PACK_STR = '!HHI'
416OFP_METER_MOD_SIZE = 16
417assert (calcsize(OFP_METER_MOD_PACK_STR) + OFP_HEADER_SIZE ==
418        OFP_METER_MOD_SIZE)
419
420# enum ofp_meter
421OFPM_MAX = 0xffff0000
422OFPM_SLOWPATH = 0xfffffffd      # Meter for slow datapath, if any.
423OFPM_CONTROLLER = 0xfffffffe    # Meter for controller connection.
424OFPM_ALL = 0xffffffff           # Represents all meters for stat requests
425                                # commands.
426
427# enum ofp_meter_mod_command
428OFPMC_ADD = 0       # New meter.
429OFPMC_MODIFY = 1    # Modify specified meter.
430OFPMC_DELETE = 2    # Delete specified meter.
431
432# enum ofp_meter_flags
433OFPMF_KBPS = 1 << 0     # Rate value in kb/s (kilo-bit per second).
434OFPMF_PKTPS = 1 << 1    # Rate value in packet/sec.
435OFPMF_BURST = 1 << 2    # Do burst size.
436OFPMF_STATS = 1 << 3    # Collect statistics.
437
438# struct ofp_meter_band_header
439OFP_METER_BAND_HEADER_PACK_STR = '!HHII'
440OFP_METER_BAND_HEADER_SIZE = 12
441assert (calcsize(OFP_METER_BAND_HEADER_PACK_STR) ==
442        OFP_METER_BAND_HEADER_SIZE)
443
444# enum ofp_meter_band_type
445OFPMBT_DROP = 1                 # Drop packet.
446OFPMBT_DSCP_REMARK = 2          # Remark DSCP in the IP header.
447OFPMBT_EXPERIMENTER = 0xFFFF    # Experimenter meter band.
448
449# struct ofp_meter_band_drop
450OFP_METER_BAND_DROP_PACK_STR = '!HHII4x'
451OFP_METER_BAND_DROP_SIZE = 16
452assert (calcsize(OFP_METER_BAND_DROP_PACK_STR) ==
453        OFP_METER_BAND_DROP_SIZE)
454
455# struct ofp_meter_band_dscp_remark
456OFP_METER_BAND_DSCP_REMARK_PACK_STR = '!HHIIB3x'
457OFP_METER_BAND_DSCP_REMARK_SIZE = 16
458assert (calcsize(OFP_METER_BAND_DSCP_REMARK_PACK_STR) ==
459        OFP_METER_BAND_DSCP_REMARK_SIZE)
460
461# struct ofp_meter_band_experimenter
462OFP_METER_BAND_EXPERIMENTER_PACK_STR = '!HHIII'
463OFP_METER_BAND_EXPERIMENTER_SIZE = 16
464assert (calcsize(OFP_METER_BAND_EXPERIMENTER_PACK_STR) ==
465        OFP_METER_BAND_EXPERIMENTER_SIZE)
466
467# struct ofp_multipart_request
468OFP_MULTIPART_REQUEST_PACK_STR = '!HH4x'
469OFP_MULTIPART_REQUEST_SIZE = 16
470assert (calcsize(OFP_MULTIPART_REQUEST_PACK_STR) + OFP_HEADER_SIZE ==
471        OFP_MULTIPART_REQUEST_SIZE)
472
473# enum ofp_multipart_request_flags
474OFPMPF_REQ_MORE = 1 << 0    # More requests to follow.
475
476# struct ofp_multipart_reply
477OFP_MULTIPART_REPLY_PACK_STR = '!HH4x'
478OFP_MULTIPART_REPLY_SIZE = 16
479assert (calcsize(OFP_MULTIPART_REPLY_PACK_STR) + OFP_HEADER_SIZE ==
480        OFP_MULTIPART_REPLY_SIZE)
481
482# enum ofp_multipart_reply_flags
483OFPMPF_REPLY_MORE = 1 << 0  # More replies to follow.
484
485# enum ofp_multipart_types
486OFPMP_DESC = 0
487OFPMP_FLOW = 1
488OFPMP_AGGREGATE = 2
489OFPMP_TABLE = 3
490OFPMP_PORT_STATS = 4
491OFPMP_QUEUE = 5
492OFPMP_GROUP = 6
493OFPMP_GROUP_DESC = 7
494OFPMP_GROUP_FEATURES = 8
495OFPMP_METER = 9
496OFPMP_METER_CONFIG = 10
497OFPMP_METER_FEATURES = 11
498OFPMP_TABLE_FEATURES = 12
499OFPMP_PORT_DESC = 13
500OFPMP_EXPERIMENTER = 0xffff
501
502# struct ofp_desc
503DESC_STR_LEN = 256
504DESC_STR_LEN_STR = str(DESC_STR_LEN)
505SERIAL_NUM_LEN = 32
506SERIAL_NUM_LEN_STR = str(SERIAL_NUM_LEN)
507OFP_DESC_PACK_STR = '!' + \
508                    DESC_STR_LEN_STR + 's' + \
509                    DESC_STR_LEN_STR + 's' + \
510                    DESC_STR_LEN_STR + 's' + \
511                    SERIAL_NUM_LEN_STR + 's' + \
512                    DESC_STR_LEN_STR + 's'
513OFP_DESC_SIZE = 1056
514assert calcsize(OFP_DESC_PACK_STR) == OFP_DESC_SIZE
515
516
517# struct ofp_flow_stats_request
518_OFP_FLOW_STATS_REQUEST_0_PACK_STR = 'B3xII4xQQ'
519OFP_FLOW_STATS_REQUEST_0_PACK_STR = '!' + _OFP_FLOW_STATS_REQUEST_0_PACK_STR
520OFP_FLOW_STATS_REQUEST_0_SIZE = 32
521assert (calcsize(OFP_FLOW_STATS_REQUEST_0_PACK_STR) ==
522        OFP_FLOW_STATS_REQUEST_0_SIZE)
523OFP_FLOW_STATS_REQUEST_PACK_STR = (OFP_FLOW_STATS_REQUEST_0_PACK_STR +
524                                   _OFP_MATCH_PACK_STR)
525OFP_FLOW_STATS_REQUEST_SIZE = 40
526assert (calcsize(OFP_FLOW_STATS_REQUEST_PACK_STR) ==
527        OFP_FLOW_STATS_REQUEST_SIZE)
528
529# struct ofp_flow_stats
530_OFP_FLOW_STATS_0_PACK_STR = 'HBxIIHHHH4xQQQ'
531OFP_FLOW_STATS_0_PACK_STR = '!' + _OFP_FLOW_STATS_0_PACK_STR
532OFP_FLOW_STATS_0_SIZE = 48
533assert calcsize(OFP_FLOW_STATS_0_PACK_STR) == OFP_FLOW_STATS_0_SIZE
534OFP_FLOW_STATS_PACK_STR = (OFP_FLOW_STATS_0_PACK_STR +
535                           _OFP_MATCH_PACK_STR)
536OFP_FLOW_STATS_SIZE = 56
537assert calcsize(OFP_FLOW_STATS_PACK_STR) == OFP_FLOW_STATS_SIZE
538
539# struct ofp_flow_stats_request
540_OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR = 'B3xII4xQQ'
541OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR = '!' + \
542    _OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR
543OFP_AGGREGATE_STATS_REQUEST_0_SIZE = 32
544assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR) ==
545        OFP_AGGREGATE_STATS_REQUEST_0_SIZE)
546OFP_AGGREGATE_STATS_REQUEST_PACK_STR = \
547    OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR + _OFP_MATCH_PACK_STR
548OFP_AGGREGATE_STATS_REQUEST_SIZE = 40
549assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_PACK_STR) ==
550        OFP_AGGREGATE_STATS_REQUEST_SIZE)
551
552# struct ofp_aggregate_stats_request
553OFP_AGGREGATE_STATS_REQUEST_PACK_STR = '!B3xII4xQQ' + _OFP_MATCH_PACK_STR
554OFP_AGGREGATE_STATS_REQUEST_SIZE = 40
555assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_PACK_STR) ==
556        OFP_AGGREGATE_STATS_REQUEST_SIZE)
557
558# struct ofp_aggregate_stats_reply
559OFP_AGGREGATE_STATS_REPLY_PACK_STR = '!QQI4x'
560OFP_AGGREGATE_STATS_REPLY_SIZE = 24
561assert (calcsize(OFP_AGGREGATE_STATS_REPLY_PACK_STR) ==
562        OFP_AGGREGATE_STATS_REPLY_SIZE)
563
564# struct ofp_table_stats
565OFP_TABLE_STATS_PACK_STR = '!B3xIQQ'
566OFP_TABLE_STATS_SIZE = 24
567assert calcsize(OFP_TABLE_STATS_PACK_STR) == OFP_TABLE_STATS_SIZE
568
569# struct ofp_table_features
570OFP_MAX_TABLE_NAME_LEN = 32
571OFP_MAX_TABLE_NAME_LEN_STR = str(OFP_MAX_TABLE_NAME_LEN)
572OFP_TABLE_FEATURES_PACK_STR = '!HB5x' + OFP_MAX_TABLE_NAME_LEN_STR + \
573                              's' + 'QQII'
574OFP_TABLE_FEATURES_SIZE = 64
575assert (calcsize(OFP_TABLE_FEATURES_PACK_STR) ==
576        OFP_TABLE_FEATURES_SIZE)
577
578# enum ofp_table_feature_prop_type
579OFPTFPT_INSTRUCTIONS = 0
580OFPTFPT_INSTRUCTIONS_MISS = 1
581OFPTFPT_NEXT_TABLES = 2
582OFPTFPT_NEXT_TABLES_MISS = 3
583OFPTFPT_WRITE_ACTIONS = 4
584OFPTFPT_WRITE_ACTIONS_MISS = 5
585OFPTFPT_APPLY_ACTIONS = 6
586OFPTFPT_APPLY_ACTIONS_MISS = 7
587OFPTFPT_MATCH = 8
588OFPTFPT_WILDCARDS = 10
589OFPTFPT_WRITE_SETFIELD = 12
590OFPTFPT_WRITE_SETFIELD_MISS = 13
591OFPTFPT_APPLY_SETFIELD = 14
592OFPTFPT_APPLY_SETFIELD_MISS = 15
593OFPTFPT_EXPERIMENTER = 0xFFFE
594OFPTFPT_EXPERIMENTER_MISS = 0xFFFF
595
596# struct ofp_table_feature_prop_instructions
597OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR = '!HH'
598OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE = 4
599assert (calcsize(OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR) ==
600        OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE)
601
602# struct ofp_table_feature_prop_next_tables
603OFP_TABLE_FEATURE_PROP_NEXT_TABLES_PACK_STR = '!HH'
604OFP_TABLE_FEATURE_PROP_NEXT_TABLES_SIZE = 4
605assert (calcsize(OFP_TABLE_FEATURE_PROP_NEXT_TABLES_PACK_STR) ==
606        OFP_TABLE_FEATURE_PROP_NEXT_TABLES_SIZE)
607
608# struct ofp_table_feature_prop_actions
609OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR = '!HH'
610OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE = 4
611assert (calcsize(OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR) ==
612        OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE)
613
614# struct ofp_table_feature_prop_oxm
615OFP_TABLE_FEATURE_PROP_OXM_PACK_STR = '!HH'
616OFP_TABLE_FEATURE_PROP_OXM_SIZE = 4
617assert (calcsize(OFP_TABLE_FEATURE_PROP_OXM_PACK_STR) ==
618        OFP_TABLE_FEATURE_PROP_OXM_SIZE)
619
620# struct ofp_port_stats_request
621OFP_PORT_STATS_REQUEST_PACK_STR = '!I4x'
622OFP_PORT_STATS_REQUEST_SIZE = 8
623assert (calcsize(OFP_PORT_STATS_REQUEST_PACK_STR) ==
624        OFP_PORT_STATS_REQUEST_SIZE)
625
626# struct ofp_port_stats
627OFP_PORT_STATS_PACK_STR = '!I4xQQQQQQQQQQQQII'
628OFP_PORT_STATS_SIZE = 112
629assert calcsize(OFP_PORT_STATS_PACK_STR) == OFP_PORT_STATS_SIZE
630
631# struct ofp_queue_stats_request
632OFP_QUEUE_STATS_REQUEST_PACK_STR = '!II'
633OFP_QUEUE_STATS_REQUEST_SIZE = 8
634assert (calcsize(OFP_QUEUE_STATS_REQUEST_PACK_STR) ==
635        OFP_QUEUE_STATS_REQUEST_SIZE)
636
637# struct ofp_queue_stats
638OFP_QUEUE_STATS_PACK_STR = '!IIQQQII'
639OFP_QUEUE_STATS_SIZE = 40
640assert calcsize(OFP_QUEUE_STATS_PACK_STR) == OFP_QUEUE_STATS_SIZE
641
642# struct ofp_group_stats_request
643OFP_GROUP_STATS_REQUEST_PACK_STR = '!I4x'
644OFP_GROUP_STATS_REQUEST_SIZE = 8
645assert (calcsize(OFP_GROUP_STATS_REQUEST_PACK_STR) ==
646        OFP_GROUP_STATS_REQUEST_SIZE)
647
648# struct ofp_group_stats
649OFP_GROUP_STATS_PACK_STR = '!H2xII4xQQII'
650OFP_GROUP_STATS_SIZE = 40
651assert calcsize(OFP_GROUP_STATS_PACK_STR) == OFP_GROUP_STATS_SIZE
652
653# struct ofp_bucket_counter
654OFP_BUCKET_COUNTER_PACK_STR = '!QQ'
655OFP_BUCKET_COUNTER_SIZE = 16
656assert calcsize(OFP_BUCKET_COUNTER_PACK_STR) == OFP_BUCKET_COUNTER_SIZE
657
658# struct ofp_group_desc
659OFP_GROUP_DESC_PACK_STR = '!HBxI'
660OFP_GROUP_DESC_SIZE = 8
661assert calcsize(OFP_GROUP_DESC_PACK_STR) == OFP_GROUP_DESC_SIZE
662
663# struct ofp_group_desc_stats
664OFP_GROUP_DESC_STATS_PACK_STR = OFP_GROUP_DESC_PACK_STR
665OFP_GROUP_DESC_STATS_SIZE = OFP_GROUP_DESC_SIZE
666assert calcsize(OFP_GROUP_DESC_STATS_PACK_STR) == OFP_GROUP_DESC_STATS_SIZE
667
668# struct ofp_group_features
669OFP_GROUP_FEATURES_PACK_STR = '!II4I4I'
670OFP_GROUP_FEATURES_SIZE = 40
671assert calcsize(OFP_GROUP_FEATURES_PACK_STR) == OFP_GROUP_FEATURES_SIZE
672
673# enum ofp_group_capabilities
674OFPGFC_SELECT_WEIGHT = 1 << 0       # Support weight for select groups.
675OFPGFC_SELECT_LIVENESS = 1 << 1     # Support liveness for select groups.
676OFPGFC_CHAINING = 1 << 2            # Support chaining groups.
677OFPGFC_CHAINING_CHECKS = 1 << 3     # Check chaining for loops and delete
678
679# struct ofp_meter_multipart_request
680OFP_METER_MULTIPART_REQUEST_PACK_STR = '!I4x'
681OFP_METER_MULTIPART_REQUEST_SIZE = 8
682assert (calcsize(OFP_METER_MULTIPART_REQUEST_PACK_STR) ==
683        OFP_METER_MULTIPART_REQUEST_SIZE)
684
685# struct ofp_meter_stats
686OFP_METER_STATS_PACK_STR = '!IH6xIQQII'
687OFP_METER_STATS_SIZE = 40
688assert calcsize(OFP_METER_STATS_PACK_STR) == OFP_METER_STATS_SIZE
689
690# struct ofp_meter_band_stats
691OFP_METER_BAND_STATS_PACK_STR = '!QQ'
692OFP_METER_BAND_STATS_SIZE = 16
693assert (calcsize(OFP_METER_BAND_STATS_PACK_STR) ==
694        OFP_METER_BAND_STATS_SIZE)
695
696# struct ofp_meter_config
697OFP_METER_CONFIG_PACK_STR = '!HHI'
698OFP_METER_CONFIG_SIZE = 8
699assert calcsize(OFP_METER_CONFIG_PACK_STR) == OFP_METER_CONFIG_SIZE
700
701# struct ofp_meter_features
702OFP_METER_FEATURES_PACK_STR = '!IIIBB2x'
703OFP_METER_FEATURES_SIZE = 16
704assert (calcsize(OFP_METER_FEATURES_PACK_STR) ==
705        OFP_METER_FEATURES_SIZE)
706
707# struct ofp_experimenter_multipart_header
708OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR = '!II'
709OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE = 8
710assert (calcsize(OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR) ==
711        OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE)
712
713# struct ofp_queue_get_config_request
714OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR = '!I4x'
715OFP_QUEUE_GET_CONFIG_REQUEST_SIZE = 16
716assert (calcsize(OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR) +
717        OFP_HEADER_SIZE) == OFP_QUEUE_GET_CONFIG_REQUEST_SIZE
718
719# struct ofp_queue_get_config_reply
720OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR = '!I4x'
721OFP_QUEUE_GET_CONFIG_REPLY_SIZE = 16
722assert (calcsize(OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR) +
723        OFP_HEADER_SIZE) == OFP_QUEUE_GET_CONFIG_REPLY_SIZE
724
725# struct ofp_packet_out
726OFP_PACKET_OUT_PACK_STR = '!IIH6x'
727OFP_PACKET_OUT_SIZE = 24
728assert (calcsize(OFP_PACKET_OUT_PACK_STR) + OFP_HEADER_SIZE ==
729        OFP_PACKET_OUT_SIZE)
730
731# struct ofp_role_request
732OFP_ROLE_REQUEST_PACK_STR = '!I4xQ'
733OFP_ROLE_REQUEST_SIZE = 24
734assert (calcsize(OFP_ROLE_REQUEST_PACK_STR) + OFP_HEADER_SIZE ==
735        OFP_ROLE_REQUEST_SIZE)
736
737# enum ofp_controller_role
738OFPCR_ROLE_NOCHANGE = 0     # Don't change current role.
739OFPCR_ROLE_EQUAL = 1        # Default role, full access.
740OFPCR_ROLE_MASTER = 2       # Full access, at most one master.
741OFPCR_ROLE_SLAVE = 3        # Read-only access.
742
743# struct ofp_async_config
744OFP_ASYNC_CONFIG_PACK_STR = '!2I2I2I'
745OFP_ASYNC_CONFIG_SIZE = 32
746assert (calcsize(OFP_ASYNC_CONFIG_PACK_STR) + OFP_HEADER_SIZE ==
747        OFP_ASYNC_CONFIG_SIZE)
748
749# struct ofp_packet_in
750OFP_PACKET_IN_PACK_STR = '!IHBBQ'
751OFP_PACKET_IN_SIZE = 32
752assert (calcsize(OFP_PACKET_IN_PACK_STR) + OFP_MATCH_SIZE + OFP_HEADER_SIZE ==
753        OFP_PACKET_IN_SIZE)
754
755# enum ofp_packet_in_reason
756OFPR_NO_MATCH = 0       # No matching flow.
757OFPR_ACTION = 1         # Action explicitly output to controller.
758OFPR_INVALID_TTL = 2    # Packet has invalid TTL.
759
760# struct ofp_flow_removed
761_OFP_FLOW_REMOVED_PACK_STR0 = 'QHBBIIHHQQ'
762OFP_FLOW_REMOVED_PACK_STR = '!' + _OFP_FLOW_REMOVED_PACK_STR0 + \
763                            _OFP_MATCH_PACK_STR
764OFP_FLOW_REMOVED_PACK_STR0 = '!' + _OFP_FLOW_REMOVED_PACK_STR0
765OFP_FLOW_REMOVED_SIZE = 56
766assert (calcsize(OFP_FLOW_REMOVED_PACK_STR) + OFP_HEADER_SIZE ==
767        OFP_FLOW_REMOVED_SIZE)
768
769# enum ofp_flow_removed_reason
770OFPRR_IDLE_TIMEOUT = 0  # Flow idle time exceeded idle_timeout.
771OFPRR_HARD_TIMEOUT = 1  # Time exceeded hard_timeout.
772OFPRR_DELETE = 2        # Evicted by a DELETE flow mod.
773OFPRR_GROUP_DELETE = 3  # Group was removed.
774
775# struct ofp_port_status
776OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR
777OFP_PORT_STATUS_DESC_OFFSET = OFP_HEADER_SIZE + 8
778OFP_PORT_STATUS_SIZE = 80
779assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE ==
780        OFP_PORT_STATUS_SIZE)
781
782# enum ofp_port_reason
783OFPPR_ADD = 0       # The port was added.
784OFPPR_DELETE = 1    # The port was removed.
785OFPPR_MODIFY = 2    # Some attribute of the port has changed.
786
787# OFPMP_EXPERIMENTER
788# struct onf_experimenter_multipart_msg
789# (experimenter == ONF_EXPERIMENTER_ID)
790ONFMP_FLOW_MONITOR = 1870
791
792# EXT-187 seems to have a lot of flaws.
793# XXX the spec mentions ONFST_FLOW_MONITOR in some places.
794# we assume it's same as ONFMP_FLOW_MONITOR.
795# XXX the spec uses OFPP_NONE.  we assume it means OFPP_ANY.
796# XXX onf_flow_update_full.length is commented to be 24.
797# but it needs to tell the actual length of instructions.
798# we assume it's variable.
799# XXX the spec seems confused between instructions and actions
800# for onf_flow_update_full/ONFFMF_ACTIONS.  we assume they all
801# are instructions.
802# XXX the spec does not define payload structures for any of
803# ONFT_FLOW_MONITOR_CANCEL, ONFT_FLOW_MONITOR_PAUSED, or
804# ONFT_FLOW_MONITOR_RESUMED.  we assume they are same as NX.
805# according to NX spec (OVS nicira-ext.h and ofp-msg.h):
806#    NXT_FLOW_MONITOR_CANCEL: a single u32 'id'.
807#    NXT_FLOW_MONITOR_PAUSED/RESUMED: empty payload
808# (OF1.4 uses something different; OFPFMC_DELETE for CANCEL and
809# OFPFME_ for PAUSED/RESUMED.)
810# XXX onf_flow_monitor_request and onf_flow_update_full use
811# match_len + oxm_fields instead of ofp_match.  this pointless
812# diverge from OF1.4 looks like a botch when updating from OF1.0.
813# XXX the spec mentions "the current implementation of Open vSwitch"
814# but, as of writing this, it doesn't have this extension implemented
815# at all.  we assume that it is about OF1.0 NX.
816# XXX the spec mentions nx13_flow_monitor_request but i couldn't find
817# it in OVS nicira-ext.h.
818
819# onf_flow_monitor_request
820# ONFMP_FLOW_MONITOR request's body is zero or more instances of this.
821# id, flags, match_len, out_put, table_id, zeros[3]
822ONF_FLOW_MONITOR_REQUEST_PACK_STR = '!IHHIB3x'
823ONF_FLOW_MONITOR_REQUEST_SIZE = 16
824assert (calcsize(ONF_FLOW_MONITOR_REQUEST_PACK_STR) ==
825        ONF_FLOW_MONITOR_REQUEST_SIZE)
826
827# onf_flow_monitor_request.flags
828ONFFMF_INITIAL = 1 << 0
829ONFFMF_ADD = 1 << 1
830ONFFMF_DELETE = 1 << 2
831ONFFMF_MODIFY = 1 << 3
832ONFFMF_ACTIONS = 1 << 4
833ONFFMF_OWN = 1 << 5
834
835# onf_flow_update_header
836# ONFMP_FLOW_MONITOR request's body is an array of this
837# length, event
838ONF_FLOW_UPDATE_HEADER_PACK_STR = '!HH'
839ONF_FLOW_UPDATE_HEADER_SIZE = 4
840assert (calcsize(ONF_FLOW_UPDATE_HEADER_PACK_STR) ==
841        ONF_FLOW_UPDATE_HEADER_SIZE)
842
843# onf_flow_update_full, excluding onf_flow_update_header
844# reason, priority, idle_timeout, hard_timeout, match_len, table_id,
845# pad, cookie
846ONF_FLOW_UPDATE_FULL_PACK_STR = '!HHHHHBxQ'
847ONF_FLOW_UPDATE_FULL_SIZE = 24 - ONF_FLOW_UPDATE_HEADER_SIZE
848assert (calcsize(ONF_FLOW_UPDATE_FULL_PACK_STR) ==
849        ONF_FLOW_UPDATE_FULL_SIZE)
850
851# onf_flow_update_abbrev, excluding onf_flow_update_header
852# xid
853ONF_FLOW_UPDATE_ABBREV_PACK_STR = '!I'
854ONF_FLOW_UPDATE_ABBREV_SIZE = 8 - ONF_FLOW_UPDATE_HEADER_SIZE
855assert (calcsize(ONF_FLOW_UPDATE_ABBREV_PACK_STR) ==
856        ONF_FLOW_UPDATE_ABBREV_SIZE)
857
858# enum onf_flow_udpate_event
859ONFFME_ADDED = 0    # some variations in the spec; ONFMFE_ADD, ONFFME_ADD
860ONFFME_DELETED = 1
861ONFFME_MODIFIED = 2
862ONFFME_ABBREV = 3
863
864# enum onf_flow_monitor_msg_type
865ONFT_FLOW_MONITOR_CANCEL = 1870     # controller -> switch
866ONFT_FLOW_MONITOR_PAUSED = 1871     # switch -> controller
867ONFT_FLOW_MONITOR_RESUMED = 1872    # switch -> controller
868
869# EXT-230 Bundle extension
870
871# enum onf_exp_type
872ONF_ET_BUNDLE_CONTROL = 2300
873ONF_ET_BUNDLE_ADD_MESSAGE = 2301
874
875ONF_BUNDLE_CTRL_PACK_STR = '!IHH'
876ONF_BUNDLE_CTRL_SIZE = 8
877assert (calcsize(ONF_BUNDLE_CTRL_PACK_STR) ==
878        ONF_BUNDLE_CTRL_SIZE)
879
880ONF_BUNDLE_ADD_MSG_PACK_STR = '!I2xH'
881ONF_BUNDLE_ADD_MSG_SIZE = 16 - OFP_HEADER_SIZE
882assert (calcsize(ONF_BUNDLE_ADD_MSG_PACK_STR) ==
883        ONF_BUNDLE_ADD_MSG_SIZE)
884
885# enum onf_bundle_ctrl_type
886ONF_BCT_OPEN_REQUEST = 0
887ONF_BCT_OPEN_REPLY = 1
888ONF_BCT_CLOSE_REQUEST = 2
889ONF_BCT_CLOSE_REPLY = 3
890ONF_BCT_COMMIT_REQUEST = 4
891ONF_BCT_COMMIT_REPLY = 5
892ONF_BCT_DISCARD_REQUEST = 6
893ONF_BCT_DISCARD_REPLY = 7
894
895# enum onf_bundle_flags
896ONF_BF_ATOMIC = 1 << 0
897ONF_BF_ORDERED = 1 << 1
898
899# enum onf_bundle_prop_type
900ONF_ET_BPT_EXPERIMENTER = 0xffff
901
902# struct ofp_error_msg
903OFP_ERROR_MSG_PACK_STR = '!HH'
904OFP_ERROR_MSG_SIZE = 12
905assert (calcsize(OFP_ERROR_MSG_PACK_STR) + OFP_HEADER_SIZE ==
906        OFP_ERROR_MSG_SIZE)
907
908# enum ofp_error_type
909OFPET_HELLO_FAILED = 0              # Hello protocol failed.
910OFPET_BAD_REQUEST = 1               # Request was not understood.
911OFPET_BAD_ACTION = 2                # Error in action description.
912OFPET_BAD_INSTRUCTION = 3           # Error in instruction list.
913OFPET_BAD_MATCH = 4                 # Error in match.
914OFPET_FLOW_MOD_FAILED = 5           # Problem modifying flow entry.
915OFPET_GROUP_MOD_FAILED = 6          # Problem modifying group entry.
916OFPET_PORT_MOD_FAILED = 7           # OFPT_PORT_MOD failed.
917OFPET_TABLE_MOD_FAILED = 8          # Table mod request failed.
918OFPET_QUEUE_OP_FAILED = 9           # Queue operation failed.
919OFPET_SWITCH_CONFIG_FAILED = 10     # Switch config request failed.
920OFPET_ROLE_REQUEST_FAILED = 11      # Controller Role request failed.
921OFPET_METER_MOD_FAILED = 12         # Error in meter.
922OFPET_TABLE_FEATURES_FAILED = 13    # Setting table features failed.
923OFPET_EXPERIMENTER = 0xffff         # Experimenter error messages.
924
925# enum ofp_hello_failed_code
926OFPHFC_INCOMPATIBLE = 0     # No compatible version.
927OFPHFC_EPERM = 1            # Permissions error.
928
929# enum ofp_bad_request_code
930OFPBRC_BAD_VERSION = 0                  # ofp_header.version not supported.
931OFPBRC_BAD_TYPE = 1                     # ofp_header.type not supported.
932OFPBRC_BAD_MULTIPART = 2                # ofp_multipart_request.type not
933                                        # supported.
934OFPBRC_BAD_EXPERIMENTER = 3             # Experimenter id not supported
935                                        # (in ofp_experimenter_header
936                                        # or ofp_multipart_request or
937                                        # ofp_multipart_reply).
938OFPBRC_BAD_EXP_TYPE = 4                 # Experimenter type not supported.
939OFPBRC_EPERM = 5                        # Permissions error.
940OFPBRC_BAD_LEN = 6                      # Wrong request length for type.
941OFPBRC_BUFFER_EMPTY = 7                 # Specified buffer has already been
942                                        # used.
943OFPBRC_BUFFER_UNKNOWN = 8               # Specified buffer does not exist.
944OFPBRC_BAD_TABLE_ID = 9                 # Specified table-id invalid or does
945                                        # not exist.
946OFPBRC_IS_SLAVE = 10                    # Denied because controller is slave.
947OFPBRC_BAD_PORT = 11                    # Invalid port.
948OFPBRC_BAD_PACKET = 12                  # Invalid packet in packet-out
949OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13   # ofp_multipart_request
950                                        # overflowed the assigned buffer.
951
952# enum ofp_bad_action_code
953OFPBAC_BAD_TYPE = 0             # Unknown action type.
954OFPBAC_BAD_LEN = 1              # Length problem in actions.
955OFPBAC_BAD_EXPERIMENTER = 2     # Unknown experimenter id specified.
956OFPBAC_BAD_EXP_TYPE = 3         # Unknown action type for experimenter id.
957OFPBAC_BAD_OUT_PORT = 4         # Problem validating output action.
958OFPBAC_BAD_ARGUMENT = 5         # Bad action argument.
959OFPBAC_EPERM = 6                # Permissions error.
960OFPBAC_TOO_MANY = 7             # Can't handle this many actions.
961OFPBAC_BAD_QUEUE = 8            # Problem validating output queue.
962OFPBAC_BAD_OUT_GROUP = 9        # Invalid group id in forward action.
963OFPBAC_MATCH_INCONSISTENT = 10  # Action can't apply for this match,
964                                # or Set-Field missing prerequisite.
965OFPBAC_UNSUPPORTED_ORDER = 11   # Action order is unsupported for
966                                # the action list in an Apply-Actions
967                                # instruction
968OFPBAC_BAD_TAG = 12             # Actions uses an unsupported tag/encap.
969OFPBAC_BAD_SET_TYPE = 13        # Unsupported type in SET_FIELD action.
970OFPBAC_BAD_SET_LEN = 14         # Length problem in SET_FIELD action.
971OFPBAC_BAD_SET_ARGUMENT = 15    # Bad arguement in SET_FIELD action.
972
973# enum ofp_bad_instruction_code
974OFPBIC_UNKNOWN_INST = 0         # Unknown instruction.
975OFPBIC_UNSUP_INST = 1           # Switch or table does not support
976                                # the instruction.
977OFPBIC_BAD_TABLE_ID = 2         # Invalid Table-Id specified
978OFPBIC_UNSUP_METADATA = 3       # Metadata value unsupported by datapath.
979OFPBIC_UNSUP_METADATA_MASK = 4  # Metadata mask value unsupported by
980                                # datapath.
981OFPBIC_BAD_EXPERIMENTER = 5     # Unknown experimenter id specified.
982OFPBIC_BAD_EXP_TYPE = 6         # Unknown instruction for experimenter id.
983OFPBIC_BAD_LEN = 7              # Length problem in instrucitons.
984OFPBIC_EPERM = 8                # Permissions error.
985
986# enum ofp_bad_match_code
987OFPBMC_BAD_TYPE = 0             # Unsupported match type apecified by
988                                # the match.
989OFPBMC_BAD_LEN = 1              # Length problem in math.
990OFPBMC_BAD_TAG = 2              # Match uses an unsupported tag/encap.
991OFPBMC_BAD_DL_ADDR_MASK = 3     # Unsupported datalink addr mask -
992                                # switch does not support arbitrary
993                                # datalink address mask.
994OFPBMC_BAD_NW_ADDR_MASK = 4     # Unsupported network addr mask -
995                                # switch does not support arbitrary
996                                # network addres mask.
997OFPBMC_BAD_WILDCARDS = 5        # Unsupported combination of fields
998                                # masked or omitted in the match.
999OFPBMC_BAD_FIELD = 6            # Unsupported field type in the match.
1000OFPBMC_BAD_VALUE = 7            # Unsupported value in a match field.
1001OFPBMC_BAD_MASK = 8             # Unsupported mask specified in the
1002                                # match.
1003OFPBMC_BAD_PREREQ = 9           # A prerequisite was not met.
1004OFPBMC_DUP_FIELD = 10           # A field type was duplicated.
1005OFPBMC_EPERM = 11               # Permissions error.
1006
1007# enum ofp_flow_mod_failed_code
1008OFPFMFC_UNKNOWN = 0             # Unspecified error.
1009OFPFMFC_TABLE_FULL = 1          # Flow not added because table was full.
1010OFPFMFC_BAD_TABLE_ID = 2        # Table does not exist
1011OFPFMFC_OVERLAP = 3             # Attempted to add overlapping flow
1012                                # with CHECK_OVERLAP flag set.
1013OFPFMFC_EPERM = 4               # Permissions error.
1014OFPFMFC_BAD_TIMEOUT = 5         # Flow not added because of
1015                                # unsupported idle/hard timeout.
1016OFPFMFC_BAD_COMMAND = 6         # Unsupported or unknown command.
1017OFPFMFC_BAD_FLAGS = 7           # Unsupported or unknown flags.
1018
1019# enum ofp_group_mod_failed_code
1020OFPGMFC_GROUP_EXISTS = 0
1021OFPGMFC_INVALID_GROUP = 1
1022OFPGMFC_WEIGHT_UNSUPPORTED = 2      # Switch does not support unequal load
1023                                    # sharing with select groups.
1024OFPGMFC_OUT_OF_GROUPS = 3           # The group table is full.
1025OFPGMFC_OUT_OF_BUCKETS = 4          # The maximum number of action buckets
1026                                    # for a group has been exceeded.
1027OFPGMFC_CHAINING_UNSUPPORTED = 5    # Switch does not support groups that
1028                                    # forward to groups.
1029OFPGMFC_WATCH_UNSUPPORTED = 6       # This group cannot watch the
1030                                    # watch_port or watch_group specified.
1031OFPGMFC_LOOP = 7                    # Group entry would cause a loop.
1032OFPGMFC_UNKNOWN_GROUP = 8           # Group not modified because a group
1033                                    # MODIFY attempted to modify a
1034                                    # non-existent group.
1035OFPGMFC_CHAINED_GROUP = 9           # Group not deleted because another
1036                                    # group is forwarding to it.
1037OFPGMFC_BAD_TYPE = 10               # Unsupported or unknown group type.
1038OFPGMFC_BAD_COMMAND = 11            # Unsupported or unknown command.
1039OFPGMFC_BAD_BUCKET = 12             # Error in bucket.
1040OFPGMFC_BAD_WATCH = 13              # Error in watch port/group.
1041OFPGMFC_EPERM = 14                  # Permissions error.
1042
1043# enum ofp_port_mod_failed_code
1044OFPPMFC_BAD_PORT = 0        # Specified port does not exist.
1045OFPPMFC_BAD_HW_ADDR = 1     # Specified hardware address does not
1046                            # match the port number.
1047OFPPMFC_BAD_CONFIG = 2      # Specified config is invalid.
1048OFPPMFC_BAD_ADVERTISE = 3   # Specified advertise is invalid.
1049OFPPMFC_EPERM = 4           # Permissions error.
1050
1051# enum ofp_table_mod_failed_code
1052OFPTMFC_BAD_TABLE = 0       # Specified table does not exist.
1053OFPTMFC_BAD_CONFIG = 1      # Specified config is invalid.
1054OFPTMFC_EPERM = 2           # Permissions error
1055
1056# enum ofp_queue_op_failed_code
1057OFPQOFC_BAD_PORT = 0        # Invalid port (or port does not exist).
1058OFPQOFC_BAD_QUEUE = 1       # Queue does not exist.
1059OFPQOFC_EPERM = 2           # Permissions error.
1060
1061# enum ofp_switch_config_failed_code
1062OFPSCFC_BAD_FLAGS = 0       # Specified flags is invalid.
1063OFPSCFC_BAD_LEN = 1         # Specified len is invalid.
1064OFPQCFC_EPERM = 2           # Permissions error (depracated).
1065                            # New or updated Ryu applications shall use
1066                            # OFPSCFC_EPERM. The variable name is a typo of
1067                            # in specifications before v1.3.1 (EXT-208).
1068OFPSCFC_EPERM = 2           # Permissions error.
1069
1070# enum ofp_role_request_failed_code
1071OFPRRFC_STALE = 0           # Stale Message: old generation_id.
1072OFPRRFC_UNSUP = 1           # Controller role change unsupported.
1073OFPRRFC_BAD_ROLE = 2        # Invalid role.
1074
1075# enum ofp_meter_mod_failed_code
1076OFPMMFC_UNKNOWN = 0         # Unspecified error.
1077OFPMMFC_METER_EXISTS = 1    # Meter not added because a Meter ADD
1078                            # attempted to replace an existing Meter.
1079OFPMMFC_INVALID_METER = 2   # Meter not added because Meter specified
1080                            # is invalid.
1081OFPMMFC_UNKNOWN_METER = 3   # Meter not modified because a Meter
1082                            # MODIFY attempted to modify a non-existent
1083                            # Meter.
1084OFPMMFC_BAD_COMMAND = 4     # Unsupported or unknown command.
1085OFPMMFC_BAD_FLAGS = 5       # Flag configuration unsupported.
1086OFPMMFC_BAD_RATE = 6        # Rate unsupported.
1087OFPMMFC_BAD_BURST = 7       # Burst size unsupported.
1088OFPMMFC_BAD_BAND = 8        # Band unsupported.
1089OFPMMFC_BAD_BAND_VALUE = 9  # Band value unsupported.
1090OFPMMFC_OUT_OF_METERS = 10  # No more meters availabile.
1091OFPMMFC_OUT_OF_BANDS = 11   # The maximum number of properties
1092                            # for a meter has been exceeded.
1093
1094# enum ofp_table_features_failed_code
1095OFPTFFC_BAD_TABLE = 0       # Specified table does not exist.
1096OFPTFFC_BAD_METADATA = 1    # Invalid metadata mask.
1097OFPTFFC_BAD_TYPE = 2        # Unknown property type.
1098OFPTFFC_BAD_LEN = 3         # Length problem in properties.
1099OFPTFFC_BAD_ARGUMENT = 4    # Unsupported property value.
1100OFPTFFC_EPERM = 5           # Permissions error.
1101
1102# struct ofp_error_experimenter_msg
1103OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI'
1104OFP_ERROR_EXPERIMENTER_MSG_SIZE = 16
1105assert (calcsize(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR) +
1106        OFP_HEADER_SIZE) == OFP_ERROR_EXPERIMENTER_MSG_SIZE
1107
1108# struct ofp_experimenter_header
1109OFP_EXPERIMENTER_HEADER_PACK_STR = '!II'
1110OFP_EXPERIMENTER_HEADER_SIZE = 16
1111assert (calcsize(OFP_EXPERIMENTER_HEADER_PACK_STR) + OFP_HEADER_SIZE
1112        == OFP_EXPERIMENTER_HEADER_SIZE)
1113
1114# exp_type values for OFPET_EXPERIMENTER (experimenter=ONF_EXPERIMENTER_ID)
1115ONFERR_ET_UNKNOWN = 2300
1116ONFERR_ET_EPERM = 2301
1117ONFERR_ET_BAD_ID = 2302
1118ONFERR_ET_BUNDLE_EXIST = 2303
1119ONFERR_ET_BUNDLE_CLOSED = 2304
1120ONFERR_ET_OUT_OF_BUNDLES = 2305
1121ONFERR_ET_BAD_TYPE = 2306
1122ONFERR_ET_BAD_FLAGS = 2307
1123ONFERR_ET_MSG_BAD_LEN = 2308
1124ONFERR_ET_MSG_BAD_XID = 2309
1125ONFERR_ET_MSG_UNSUP = 2310
1126ONFERR_ET_MSG_CONFLICT = 2311
1127ONFERR_ET_MSG_TOO_MANY = 2312
1128ONFERR_ET_FAILED = 2313
1129ONFERR_ET_TIMEOUT = 2314
1130ONFERR_ET_BUNDLE_IN_PROGRESS = 2315
1131ONFERR_ET_CANT_SYNC = 2320
1132ONFERR_ET_BAD_PRIORITY = 2360
1133ONFERR_ET_ASYNC_INVALUD = 2370
1134ONFERR_ET_ASYNC_UNSUPPORTED = 2371
1135ONFERR_ET_ASYNC_EPERM = 2372
1136ONFERR_DUP_INSTRUCTION = 2600   # the lack of _ET_ is per spec
1137ONFERR_ET_MPART_REQUEST_TIMEOUT = 2640
1138ONFERR_ET_MPART_REPLY_TIMEOUT = 2641
1139
1140# struct ofp_hello
1141OFP_HELLO_HEADER_SIZE = 8
1142
1143# struct ofp_hello_elem_header
1144OFP_HELLO_ELEM_HEADER_PACK_STR = '!HH'
1145OFP_HELLO_ELEM_HEADER_SIZE = 4
1146assert (calcsize(OFP_HELLO_ELEM_HEADER_PACK_STR) == OFP_HELLO_ELEM_HEADER_SIZE)
1147
1148# enum ofp_hello_elem_type
1149OFPHET_VERSIONBITMAP = 1
1150
1151# struct ofp_hello_elem_versionbitmap
1152OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR = '!HH'
1153OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE = 4
1154assert (calcsize(OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR) ==
1155        OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE)
1156
1157# OXM
1158
1159
1160def _oxm_tlv_header(class_, field, hasmask, length):
1161    return (class_ << 16) | (field << 9) | (hasmask << 8) | length
1162
1163
1164def oxm_tlv_header(field, length):
1165    return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 0, length)
1166
1167
1168def oxm_tlv_header_w(field, length):
1169    return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 1, length * 2)
1170
1171
1172def oxm_tlv_header_extract_hasmask(header):
1173    return (header >> 8) & 1
1174
1175
1176def oxm_tlv_header_extract_length(header):
1177    if oxm_tlv_header_extract_hasmask(header):
1178        length = (header & 0xff) // 2
1179    else:
1180        length = header & 0xff
1181    return length
1182
1183
1184oxm_types = [
1185    oxm_fields.OpenFlowBasic('in_port', 0, type_desc.Int4),
1186    oxm_fields.OpenFlowBasic('in_phy_port', 1, type_desc.Int4),
1187    oxm_fields.OpenFlowBasic('metadata', 2, type_desc.Int8),
1188    oxm_fields.OpenFlowBasic('eth_dst', 3, type_desc.MacAddr),
1189    oxm_fields.OpenFlowBasic('eth_src', 4, type_desc.MacAddr),
1190    oxm_fields.OpenFlowBasic('eth_type', 5, type_desc.Int2),
1191    oxm_fields.OpenFlowBasic('vlan_vid', 6, type_desc.Int2),
1192    oxm_fields.OpenFlowBasic('vlan_pcp', 7, type_desc.Int1),
1193    oxm_fields.OpenFlowBasic('ip_dscp', 8, type_desc.Int1),
1194    oxm_fields.OpenFlowBasic('ip_ecn', 9, type_desc.Int1),
1195    oxm_fields.OpenFlowBasic('ip_proto', 10, type_desc.Int1),
1196    oxm_fields.OpenFlowBasic('ipv4_src', 11, type_desc.IPv4Addr),
1197    oxm_fields.OpenFlowBasic('ipv4_dst', 12, type_desc.IPv4Addr),
1198    oxm_fields.OpenFlowBasic('tcp_src', 13, type_desc.Int2),
1199    oxm_fields.OpenFlowBasic('tcp_dst', 14, type_desc.Int2),
1200    oxm_fields.OpenFlowBasic('udp_src', 15, type_desc.Int2),
1201    oxm_fields.OpenFlowBasic('udp_dst', 16, type_desc.Int2),
1202    oxm_fields.OpenFlowBasic('sctp_src', 17, type_desc.Int2),
1203    oxm_fields.OpenFlowBasic('sctp_dst', 18, type_desc.Int2),
1204    oxm_fields.OpenFlowBasic('icmpv4_type', 19, type_desc.Int1),
1205    oxm_fields.OpenFlowBasic('icmpv4_code', 20, type_desc.Int1),
1206    oxm_fields.OpenFlowBasic('arp_op', 21, type_desc.Int2),
1207    oxm_fields.OpenFlowBasic('arp_spa', 22, type_desc.IPv4Addr),
1208    oxm_fields.OpenFlowBasic('arp_tpa', 23, type_desc.IPv4Addr),
1209    oxm_fields.OpenFlowBasic('arp_sha', 24, type_desc.MacAddr),
1210    oxm_fields.OpenFlowBasic('arp_tha', 25, type_desc.MacAddr),
1211    oxm_fields.OpenFlowBasic('ipv6_src', 26, type_desc.IPv6Addr),
1212    oxm_fields.OpenFlowBasic('ipv6_dst', 27, type_desc.IPv6Addr),
1213    oxm_fields.OpenFlowBasic('ipv6_flabel', 28, type_desc.Int4),
1214    oxm_fields.OpenFlowBasic('icmpv6_type', 29, type_desc.Int1),
1215    oxm_fields.OpenFlowBasic('icmpv6_code', 30, type_desc.Int1),
1216    oxm_fields.OpenFlowBasic('ipv6_nd_target', 31, type_desc.IPv6Addr),
1217    oxm_fields.OpenFlowBasic('ipv6_nd_sll', 32, type_desc.MacAddr),
1218    oxm_fields.OpenFlowBasic('ipv6_nd_tll', 33, type_desc.MacAddr),
1219    oxm_fields.OpenFlowBasic('mpls_label', 34, type_desc.Int4),
1220    oxm_fields.OpenFlowBasic('mpls_tc', 35, type_desc.Int1),
1221    oxm_fields.OpenFlowBasic('mpls_bos', 36, type_desc.Int1),
1222    oxm_fields.OpenFlowBasic('pbb_isid', 37, type_desc.Int3),
1223    oxm_fields.OpenFlowBasic('tunnel_id', 38, type_desc.Int8),
1224    oxm_fields.OpenFlowBasic('ipv6_exthdr', 39, type_desc.Int2),
1225    # EXT-256 Old version of ONF Extension
1226    oxm_fields.OldONFExperimenter('pbb_uca', 2560, type_desc.Int1),
1227    # EXT-109 TCP flags match field Extension
1228    oxm_fields.ONFExperimenter('tcp_flags', 42, type_desc.Int2),
1229    # EXT-233 Output match Extension
1230    # NOTE(yamamoto): The spec says uint64_t but I assume it's an error.
1231    oxm_fields.ONFExperimenter('actset_output', 43, type_desc.Int4),
1232] + nicira_ext.oxm_types
1233
1234oxm_fields.generate(__name__)
1235
1236
1237# Note: struct ofp_prop_experimenter is specific to this implementation.
1238# It does not have a corresponding structure in the specification.
1239# This structure defines common structure for ofp_*_prop_experimenter.
1240# struct ofp_prop_experimenter
1241OFP_PROP_EXPERIMENTER_PACK_STR = '!HHII'
1242OFP_PROP_EXPERIMENTER_SIZE = 12
1243assert (calcsize(OFP_PROP_EXPERIMENTER_PACK_STR) ==
1244        OFP_PROP_EXPERIMENTER_SIZE)
1245
1246# generate utility methods
1247ofproto_utils.generate(__name__)
1248
1249# define constants
1250OFP_VERSION = 0x04
1251OFP_TCP_PORT = 6633
1252MAX_XID = 0xffffffff
1253
1254OFP_NO_BUFFER = 0xffffffff
1255