backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / ofproto / nx_actions.py
1 # Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2015 YAMAMOTO Takashi <yamamoto 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 import six
18
19 import struct
20
21 from ryu import utils
22 from ryu.lib import type_desc
23 from ryu.ofproto import nicira_ext
24 from ryu.ofproto import ofproto_common
25 from ryu.lib.pack_utils import msg_pack_into
26 from ryu.ofproto.ofproto_parser import StringifyMixin
27
28
29 def generate(ofp_name, ofpp_name):
30     import sys
31
32     ofp = sys.modules[ofp_name]
33     ofpp = sys.modules[ofpp_name]
34
35     class _NXFlowSpec(StringifyMixin):
36         _hdr_fmt_str = '!H'  # 2 bit 0s, 1 bit src, 2 bit dst, 11 bit n_bits
37         _dst_type = None
38         _subclasses = {}
39         _TYPE = {
40             'nx-flow-spec-field': [
41                 'src',
42                 'dst',
43             ]
44         }
45
46         def __init__(self, src, dst, n_bits):
47             self.src = src
48             self.dst = dst
49             self.n_bits = n_bits
50
51         @classmethod
52         def register(cls, subcls):
53             assert issubclass(subcls, cls)
54             assert subcls._dst_type not in cls._subclasses
55             cls._subclasses[subcls._dst_type] = subcls
56
57         @classmethod
58         def parse(cls, buf):
59             (hdr,) = struct.unpack_from(cls._hdr_fmt_str, buf, 0)
60             rest = buf[struct.calcsize(cls._hdr_fmt_str):]
61             if hdr == 0:
62                 return None, rest  # all-0 header is no-op for padding
63             src_type = (hdr >> 13) & 0x1
64             dst_type = (hdr >> 11) & 0x3
65             n_bits = hdr & 0x3ff
66             subcls = cls._subclasses[dst_type]
67             if src_type == 0:  # subfield
68                 src = cls._parse_subfield(rest)
69                 rest = rest[6:]
70             elif src_type == 1:  # immediate
71                 src_len = (n_bits + 15) // 16 * 2
72                 src_bin = rest[:src_len]
73                 src = type_desc.IntDescr(size=src_len).to_user(src_bin)
74                 rest = rest[src_len:]
75             if dst_type == 0:  # match
76                 dst = cls._parse_subfield(rest)
77                 rest = rest[6:]
78             elif dst_type == 1:  # load
79                 dst = cls._parse_subfield(rest)
80                 rest = rest[6:]
81             elif dst_type == 2:  # output
82                 dst = ''  # empty
83             return subcls(src=src, dst=dst, n_bits=n_bits), rest
84
85         def serialize(self):
86             buf = bytearray()
87             if isinstance(self.src, tuple):
88                 src_type = 0  # subfield
89             else:
90                 src_type = 1  # immediate
91             # header
92             val = (src_type << 13) | (self._dst_type << 11) | self.n_bits
93             msg_pack_into(self._hdr_fmt_str, buf, 0, val)
94             # src
95             if src_type == 0:  # subfield
96                 buf += self._serialize_subfield(self.src)
97             elif src_type == 1:  # immediate
98                 src_len = (self.n_bits + 15) // 16 * 2
99                 buf += type_desc.IntDescr(size=src_len).from_user(self.src)
100             # dst
101             if self._dst_type == 0:  # match
102                 buf += self._serialize_subfield(self.dst)
103             elif self._dst_type == 1:  # load
104                 buf += self._serialize_subfield(self.dst)
105             elif self._dst_type == 2:  # output
106                 pass  # empty
107             return buf
108
109         @staticmethod
110         def _parse_subfield(buf):
111             (n, len) = ofp.oxm_parse_header(buf, 0)
112             assert len == 4  # only 4-bytes NXM/OXM are defined
113             field = ofp.oxm_to_user_header(n)
114             rest = buf[len:]
115             (ofs,) = struct.unpack_from('!H', rest, 0)
116             return (field, ofs)
117
118         @staticmethod
119         def _serialize_subfield(subfield):
120             (field, ofs) = subfield
121             buf = bytearray()
122             n = ofp.oxm_from_user_header(field)
123             ofp.oxm_serialize_header(n, buf, 0)
124             assert len(buf) == 4  # only 4-bytes NXM/OXM are defined
125             msg_pack_into('!H', buf, 4, ofs)
126             return buf
127
128     class NXFlowSpecMatch(_NXFlowSpec):
129         """
130         Specification for adding match criterion
131
132         This class is used by ``NXActionLearn``.
133
134         For the usage of this class, please refer to ``NXActionLearn``.
135
136         ================ ======================================================
137         Attribute        Description
138         ================ ======================================================
139         src              OXM/NXM header and Start bit for source field
140         dst              OXM/NXM header and Start bit for destination field
141         n_bits           The number of bits from the start bit
142         ================ ======================================================
143         """
144         # Add a match criteria
145         # an example of the corresponding ovs-ofctl syntax:
146         #    NXM_OF_VLAN_TCI[0..11]
147         _dst_type = 0
148
149     class NXFlowSpecLoad(_NXFlowSpec):
150         """
151         Add NXAST_REG_LOAD actions
152
153         This class is used by ``NXActionLearn``.
154
155         For the usage of this class, please refer to ``NXActionLearn``.
156
157         ================ ======================================================
158         Attribute        Description
159         ================ ======================================================
160         src              OXM/NXM header and Start bit for source field
161         dst              OXM/NXM header and Start bit for destination field
162         n_bits           The number of bits from the start bit
163         ================ ======================================================
164         """
165         # Add NXAST_REG_LOAD actions
166         # an example of the corresponding ovs-ofctl syntax:
167         #    NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
168         _dst_type = 1
169
170     class NXFlowSpecOutput(_NXFlowSpec):
171         """
172         Add an OFPAT_OUTPUT action
173
174         This class is used by ``NXActionLearn``.
175
176         For the usage of this class, please refer to ``NXActionLearn``.
177
178         ================ ======================================================
179         Attribute        Description
180         ================ ======================================================
181         src              OXM/NXM header and Start bit for source field
182         dst              Must be ''
183         n_bits           The number of bits from the start bit
184         ================ ======================================================
185         """
186         # Add an OFPAT_OUTPUT action
187         # an example of the corresponding ovs-ofctl syntax:
188         #    output:NXM_OF_IN_PORT[]
189         _dst_type = 2
190
191         def __init__(self, src, n_bits, dst=''):
192             assert dst == ''
193             super(NXFlowSpecOutput, self).__init__(src=src, dst=dst,
194                                                    n_bits=n_bits)
195
196     class NXAction(ofpp.OFPActionExperimenter):
197         _fmt_str = '!H'  # subtype
198         _subtypes = {}
199         _experimenter = ofproto_common.NX_EXPERIMENTER_ID
200
201         def __init__(self):
202             super(NXAction, self).__init__(self._experimenter)
203             self.subtype = self._subtype
204
205         @classmethod
206         def parse(cls, buf):
207             fmt_str = NXAction._fmt_str
208             (subtype,) = struct.unpack_from(fmt_str, buf, 0)
209             subtype_cls = cls._subtypes.get(subtype)
210             rest = buf[struct.calcsize(fmt_str):]
211             if subtype_cls is None:
212                 return NXActionUnknown(subtype, rest)
213             return subtype_cls.parser(rest)
214
215         def serialize(self, buf, offset):
216             data = self.serialize_body()
217             payload_offset = (
218                 ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE +
219                 struct.calcsize(NXAction._fmt_str)
220             )
221             self.len = utils.round_up(payload_offset + len(data), 8)
222             super(NXAction, self).serialize(buf, offset)
223             msg_pack_into(NXAction._fmt_str,
224                           buf,
225                           offset + ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE,
226                           self.subtype)
227             buf += data
228
229         @classmethod
230         def register(cls, subtype_cls):
231             assert subtype_cls._subtype is not cls._subtypes
232             cls._subtypes[subtype_cls._subtype] = subtype_cls
233
234     class NXActionUnknown(NXAction):
235         def __init__(self, subtype, data=None,
236                      type_=None, len_=None, experimenter=None):
237             self._subtype = subtype
238             super(NXActionUnknown, self).__init__()
239             self.data = data
240
241         @classmethod
242         def parser(cls, buf):
243             return cls(data=buf)
244
245         def serialize_body(self):
246             # fixup
247             return bytearray() if self.data is None else self.data
248
249     # For OpenFlow1.0 only
250     class NXActionSetQueue(NXAction):
251         r"""
252         Set queue action
253
254         This action sets the queue that should be used to queue
255         when packets are output.
256
257         And equivalent to the followings action of ovs-ofctl command.
258
259         ..
260           set_queue:queue
261         ..
262
263         +-------------------------+
264         | **set_queue**\:\ *queue*|
265         +-------------------------+
266
267         ================ ======================================================
268         Attribute        Description
269         ================ ======================================================
270         queue_id         Queue ID for the packets
271         ================ ======================================================
272
273         .. note::
274             This actions is supported by
275             ``OFPActionSetQueue``
276             in OpenFlow1.2 or later.
277
278         Example::
279
280             actions += [parser.NXActionSetQueue(queue_id=10)]
281         """
282         _subtype = nicira_ext.NXAST_SET_QUEUE
283
284         # queue_id
285         _fmt_str = '!2xI'
286
287         def __init__(self, queue_id,
288                      type_=None, len_=None, vendor=None, subtype=None):
289             super(NXActionSetQueue, self).__init__()
290             self.queue_id = queue_id
291
292         @classmethod
293         def parser(cls, buf):
294             (queue_id,) = struct.unpack_from(cls._fmt_str, buf, 0)
295             return cls(queue_id)
296
297         def serialize_body(self):
298             data = bytearray()
299             msg_pack_into(self._fmt_str, data, 0, self.queue_id)
300             return data
301
302     class NXActionPopQueue(NXAction):
303         """
304         Pop queue action
305
306         This action restors the queue to the value it was before any
307         set_queue actions were applied.
308
309         And equivalent to the followings action of ovs-ofctl command.
310
311         ..
312           pop_queue
313         ..
314
315         +---------------+
316         | **pop_queue** |
317         +---------------+
318
319         Example::
320
321             actions += [parser.NXActionPopQueue()]
322         """
323         _subtype = nicira_ext.NXAST_POP_QUEUE
324
325         _fmt_str = '!6x'
326
327         def __init__(self,
328                      type_=None, len_=None, experimenter=None, subtype=None):
329             super(NXActionPopQueue, self).__init__()
330
331         @classmethod
332         def parser(cls, buf):
333             return cls()
334
335         def serialize_body(self):
336             data = bytearray()
337             msg_pack_into(self._fmt_str, data, 0)
338             return data
339
340     class NXActionRegLoad(NXAction):
341         r"""
342         Load literal value action
343
344         This action loads a literal value into a field or part of a field.
345
346         And equivalent to the followings action of ovs-ofctl command.
347
348         ..
349           load:value->dst[start..end]
350         ..
351
352         +-----------------------------------------------------------------+
353         | **load**\:\ *value*\->\ *dst*\ **[**\ *start*\..\ *end*\ **]**  |
354         +-----------------------------------------------------------------+
355
356         ================ ======================================================
357         Attribute        Description
358         ================ ======================================================
359         ofs_nbits        Start and End for the OXM/NXM field.
360                          Setting method refer to the ``nicira_ext.ofs_nbits``
361         dst              OXM/NXM header for destination field
362         value            OXM/NXM value to be loaded
363         ================ ======================================================
364
365         Example::
366
367             actions += [parser.NXActionRegLoad(
368                             ofs_nbits=nicira_ext.ofs_nbits(4, 31),
369                             dst="eth_dst",
370                             value=0x112233)]
371         """
372         _subtype = nicira_ext.NXAST_REG_LOAD
373         _fmt_str = '!HIQ'  # ofs_nbits, dst, value
374         _TYPE = {
375             'ascii': [
376                 'dst',
377             ]
378         }
379
380         def __init__(self, ofs_nbits, dst, value,
381                      type_=None, len_=None, experimenter=None,
382                      subtype=None):
383             super(NXActionRegLoad, self).__init__()
384             self.ofs_nbits = ofs_nbits
385             self.dst = dst
386             self.value = value
387
388         @classmethod
389         def parser(cls, buf):
390             (ofs_nbits, dst, value,) = struct.unpack_from(
391                 cls._fmt_str, buf, 0)
392             # Right-shift instead of using oxm_parse_header for simplicity...
393             dst_name = ofp.oxm_to_user_header(dst >> 9)
394             return cls(ofs_nbits, dst_name, value)
395
396         def serialize_body(self):
397             hdr_data = bytearray()
398             n = ofp.oxm_from_user_header(self.dst)
399             ofp.oxm_serialize_header(n, hdr_data, 0)
400             (dst_num,) = struct.unpack_from('!I', six.binary_type(hdr_data), 0)
401
402             data = bytearray()
403             msg_pack_into(self._fmt_str, data, 0,
404                           self.ofs_nbits, dst_num, self.value)
405             return data
406
407     class NXActionRegLoad2(NXAction):
408         r"""
409         Load literal value action
410
411         This action loads a literal value into a field or part of a field.
412
413         And equivalent to the followings action of ovs-ofctl command.
414
415         ..
416           set_field:value[/mask]->dst
417         ..
418
419         +------------------------------------------------------------+
420         | **set_field**\:\ *value*\ **[**\/\ *mask*\ **]**\->\ *dst* |
421         +------------------------------------------------------------+
422
423         ================ ======================================================
424         Attribute        Description
425         ================ ======================================================
426         value            OXM/NXM value to be loaded
427         mask             Mask for destination field
428         dst              OXM/NXM header for destination field
429         ================ ======================================================
430
431         Example::
432
433             actions += [parser.NXActionRegLoad2(dst="tun_ipv4_src",
434                                                 value="192.168.10.0",
435                                                 mask="255.255.255.0")]
436         """
437         _subtype = nicira_ext.NXAST_REG_LOAD2
438         _TYPE = {
439             'ascii': [
440                 'dst',
441                 'value',
442             ]
443         }
444
445         def __init__(self, dst, value, mask=None,
446                      type_=None, len_=None, experimenter=None, subtype=None):
447             super(NXActionRegLoad2, self).__init__()
448             self.dst = dst
449             self.value = value
450             self.mask = mask
451
452         @classmethod
453         def parser(cls, buf):
454             (n, uv, mask, _len) = ofp.oxm_parse(buf, 0)
455             dst, value = ofp.oxm_to_user(n, uv, mask)
456
457             if isinstance(value, (tuple, list)):
458                 return cls(dst, value[0], value[1])
459             else:
460                 return cls(dst, value, None)
461
462         def serialize_body(self):
463             data = bytearray()
464             if self.mask is None:
465                 value = self.value
466             else:
467                 value = (self.value, self.mask)
468                 self._TYPE['ascii'].append('mask')
469
470             n, value, mask = ofp.oxm_from_user(self.dst, value)
471             len_ = ofp.oxm_serialize(n, value, mask, data, 0)
472             msg_pack_into("!%dx" % (14 - len_), data, len_)
473
474             return data
475
476     class NXActionNote(NXAction):
477         r"""
478         Note action
479
480         This action does nothing at all.
481
482         And equivalent to the followings action of ovs-ofctl command.
483
484         ..
485           note:[hh]..
486         ..
487
488         +-----------------------------------+
489         | **note**\:\ **[**\ *hh*\ **]**\.. |
490         +-----------------------------------+
491
492         ================ ======================================================
493         Attribute        Description
494         ================ ======================================================
495         note             A list of integer type values
496         ================ ======================================================
497
498         Example::
499
500             actions += [parser.NXActionNote(note=[0xaa,0xbb,0xcc,0xdd])]
501         """
502         _subtype = nicira_ext.NXAST_NOTE
503
504         # note
505         _fmt_str = '!%dB'
506
507         # set the integer array in a note
508         def __init__(self,
509                      note,
510                      type_=None, len_=None, experimenter=None, subtype=None):
511             super(NXActionNote, self).__init__()
512             self.note = note
513
514         @classmethod
515         def parser(cls, buf):
516             note = struct.unpack_from(
517                 cls._fmt_str % len(buf), buf, 0)
518             return cls(list(note))
519
520         def serialize_body(self):
521             assert isinstance(self.note, (tuple, list))
522             for n in self.note:
523                 assert isinstance(n, six.integer_types)
524
525             pad = (len(self.note) + nicira_ext.NX_ACTION_HEADER_0_SIZE) % 8
526             if pad:
527                 self.note += [0x0 for i in range(8 - pad)]
528             note_len = len(self.note)
529             data = bytearray()
530             msg_pack_into(self._fmt_str % note_len, data, 0,
531                           *self.note)
532             return data
533
534     class _NXActionSetTunnelBase(NXAction):
535         # _subtype, _fmt_str must be attributes of subclass.
536
537         def __init__(self,
538                      tun_id,
539                      type_=None, len_=None, experimenter=None, subtype=None):
540             super(_NXActionSetTunnelBase, self).__init__()
541             self.tun_id = tun_id
542
543         @classmethod
544         def parser(cls, buf):
545             (tun_id,) = struct.unpack_from(
546                 cls._fmt_str, buf, 0)
547             return cls(tun_id)
548
549         def serialize_body(self):
550             data = bytearray()
551             msg_pack_into(self._fmt_str, data, 0,
552                           self.tun_id)
553             return data
554
555     class NXActionSetTunnel(_NXActionSetTunnelBase):
556         r"""
557         Set Tunnel action
558
559         This action sets the identifier (such as GRE) to the specified id.
560
561         And equivalent to the followings action of ovs-ofctl command.
562
563         .. note::
564             This actions is supported by
565             ``OFPActionSetField``
566             in OpenFlow1.2 or later.
567
568         ..
569           set_tunnel:id
570         ..
571
572         +------------------------+
573         | **set_tunnel**\:\ *id* |
574         +------------------------+
575
576         ================ ======================================================
577         Attribute        Description
578         ================ ======================================================
579         tun_id           Tunnel ID(32bits)
580         ================ ======================================================
581
582         Example::
583
584             actions += [parser.NXActionSetTunnel(tun_id=0xa)]
585         """
586         _subtype = nicira_ext.NXAST_SET_TUNNEL
587
588         # tun_id
589         _fmt_str = '!2xI'
590
591     class NXActionSetTunnel64(_NXActionSetTunnelBase):
592         r"""
593         Set Tunnel action
594
595         This action outputs to a port that encapsulates
596         the packet in a tunnel.
597
598         And equivalent to the followings action of ovs-ofctl command.
599
600         .. note::
601             This actions is supported by
602             ``OFPActionSetField``
603             in OpenFlow1.2 or later.
604
605         ..
606           set_tunnel64:id
607         ..
608
609         +--------------------------+
610         | **set_tunnel64**\:\ *id* |
611         +--------------------------+
612
613         ================ ======================================================
614         Attribute        Description
615         ================ ======================================================
616         tun_id           Tunnel ID(64bits)
617         ================ ======================================================
618
619         Example::
620
621             actions += [parser.NXActionSetTunnel64(tun_id=0xa)]
622         """
623         _subtype = nicira_ext.NXAST_SET_TUNNEL64
624
625         # tun_id
626         _fmt_str = '!6xQ'
627
628     class NXActionRegMove(NXAction):
629         r"""
630         Move register action
631
632         This action copies the src to dst.
633
634         And equivalent to the followings action of ovs-ofctl command.
635
636         ..
637           move:src[start..end]->dst[start..end]
638         ..
639
640         +--------------------------------------------------------+
641         | **move**\:\ *src*\ **[**\ *start*\..\ *end*\ **]**\->\ |
642         | *dst*\ **[**\ *start*\..\ *end* \ **]**                |
643         +--------------------------------------------------------+
644
645         ================ ======================================================
646         Attribute        Description
647         ================ ======================================================
648         src_field        OXM/NXM header for source field
649         dst_field        OXM/NXM header for destination field
650         n_bits           Number of bits
651         src_ofs          Starting bit offset in source
652         dst_ofs          Starting bit offset in destination
653         ================ ======================================================
654
655         .. CAUTION::
656             **src_start**\  and \ **src_end**\  difference and \ **dst_start**\
657              and \ **dst_end**\  difference must be the same.
658
659         Example::
660
661             actions += [parser.NXActionRegMove(src_field="reg0",
662                                                dst_field="reg1",
663                                                n_bits=5,
664                                                src_ofs=0
665                                                dst_ofs=10)]
666         """
667         _subtype = nicira_ext.NXAST_REG_MOVE
668         _fmt_str = '!HHH'  # n_bits, src_ofs, dst_ofs
669         # Followed by OXM fields (src, dst) and padding to 8 bytes boundary
670         _TYPE = {
671             'ascii': [
672                 'src_field',
673                 'dst_field',
674             ]
675         }
676
677         def __init__(self, src_field, dst_field, n_bits, src_ofs=0, dst_ofs=0,
678                      type_=None, len_=None, experimenter=None, subtype=None):
679             super(NXActionRegMove, self).__init__()
680             self.n_bits = n_bits
681             self.src_ofs = src_ofs
682             self.dst_ofs = dst_ofs
683             self.src_field = src_field
684             self.dst_field = dst_field
685
686         @classmethod
687         def parser(cls, buf):
688             (n_bits, src_ofs, dst_ofs,) = struct.unpack_from(
689                 cls._fmt_str, buf, 0)
690             rest = buf[struct.calcsize(NXActionRegMove._fmt_str):]
691
692             # src field
693             (n, len) = ofp.oxm_parse_header(rest, 0)
694             src_field = ofp.oxm_to_user_header(n)
695             rest = rest[len:]
696             # dst field
697             (n, len) = ofp.oxm_parse_header(rest, 0)
698             dst_field = ofp.oxm_to_user_header(n)
699             rest = rest[len:]
700             # ignore padding
701             return cls(src_field, dst_field=dst_field, n_bits=n_bits,
702                        src_ofs=src_ofs, dst_ofs=dst_ofs)
703
704         def serialize_body(self):
705             # fixup
706             data = bytearray()
707             msg_pack_into(self._fmt_str, data, 0,
708                           self.n_bits, self.src_ofs, self.dst_ofs)
709             # src field
710             n = ofp.oxm_from_user_header(self.src_field)
711             ofp.oxm_serialize_header(n, data, len(data))
712             # dst field
713             n = ofp.oxm_from_user_header(self.dst_field)
714             ofp.oxm_serialize_header(n, data, len(data))
715             return data
716
717     class NXActionResubmit(NXAction):
718         r"""
719         Resubmit action
720
721         This action searches one of the switch's flow tables.
722
723         And equivalent to the followings action of ovs-ofctl command.
724
725         ..
726           resubmit:port
727         ..
728
729         +------------------------+
730         | **resubmit**\:\ *port* |
731         +------------------------+
732
733         ================ ======================================================
734         Attribute        Description
735         ================ ======================================================
736         in_port          New in_port for checking flow table
737         ================ ======================================================
738
739         Example::
740
741             actions += [parser.NXActionResubmit(in_port=8080)]
742         """
743         _subtype = nicira_ext.NXAST_RESUBMIT
744
745         # in_port
746         _fmt_str = '!H4x'
747
748         def __init__(self,
749                      in_port=0xfff8,
750                      type_=None, len_=None, experimenter=None, subtype=None):
751             super(NXActionResubmit, self).__init__()
752             self.in_port = in_port
753
754         @classmethod
755         def parser(cls, buf):
756             (in_port,) = struct.unpack_from(
757                 cls._fmt_str, buf, 0)
758             return cls(in_port)
759
760         def serialize_body(self):
761             data = bytearray()
762             msg_pack_into(self._fmt_str, data, 0,
763                           self.in_port)
764             return data
765
766     class NXActionResubmitTable(NXAction):
767         r"""
768         Resubmit action
769
770         This action searches one of the switch's flow tables.
771
772         And equivalent to the followings action of ovs-ofctl command.
773
774         ..
775           resubmit([port],[table])
776         ..
777
778         +------------------------------------------------+
779         | **resubmit(**\[\ *port*\]\,[\ *table*\]\ **)** |
780         +------------------------------------------------+
781
782         ================ ======================================================
783         Attribute        Description
784         ================ ======================================================
785         in_port          New in_port for checking flow table
786         table_id         Checking flow tables
787         ================ ======================================================
788
789         Example::
790
791             actions += [parser.NXActionResubmit(in_port=8080,
792                                                 table_id=10)]
793         """
794         _subtype = nicira_ext.NXAST_RESUBMIT_TABLE
795
796         # in_port, table_id
797         _fmt_str = '!HB3x'
798
799         def __init__(self,
800                      in_port=0xfff8,
801                      table_id=0xff,
802                      type_=None, len_=None, experimenter=None, subtype=None):
803             super(NXActionResubmitTable, self).__init__()
804             self.in_port = in_port
805             self.table_id = table_id
806
807         @classmethod
808         def parser(cls, buf):
809             (in_port,
810              table_id) = struct.unpack_from(
811                 cls._fmt_str, buf, 0)
812             return cls(in_port, table_id)
813
814         def serialize_body(self):
815             data = bytearray()
816             msg_pack_into(self._fmt_str, data, 0,
817                           self.in_port, self.table_id)
818             return data
819
820     class NXActionOutputReg(NXAction):
821         r"""
822         Add output action
823
824         This action outputs the packet to the OpenFlow port number read from
825         src.
826
827         And equivalent to the followings action of ovs-ofctl command.
828
829         ..
830           output:src[start...end]
831         ..
832
833         +-------------------------------------------------------+
834         | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
835         +-------------------------------------------------------+
836
837         ================ ======================================================
838         Attribute        Description
839         ================ ======================================================
840         ofs_nbits        Start and End for the OXM/NXM field.
841                          Setting method refer to the ``nicira_ext.ofs_nbits``
842         src              OXM/NXM header for source field
843         max_len          Max length to send to controller
844         ================ ======================================================
845
846         Example::
847
848             actions += [parser.NXActionOutputReg(
849                             ofs_nbits=nicira_ext.ofs_nbits(4, 31),
850                             src="reg0",
851                             max_len=1024)]
852         """
853         _subtype = nicira_ext.NXAST_OUTPUT_REG
854
855         # ofs_nbits, src, max_len
856         _fmt_str = '!H4sH6x'
857         _TYPE = {
858             'ascii': [
859                 'src',
860             ]
861         }
862
863         def __init__(self,
864                      ofs_nbits,
865                      src,
866                      max_len,
867                      type_=None, len_=None, experimenter=None, subtype=None):
868             super(NXActionOutputReg, self).__init__()
869             self.ofs_nbits = ofs_nbits
870             self.src = src
871             self.max_len = max_len
872
873         @classmethod
874         def parser(cls, buf):
875             (ofs_nbits, oxm_data, max_len) = struct.unpack_from(
876                 cls._fmt_str, buf, 0)
877             (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
878             src = ofp.oxm_to_user_header(n)
879             return cls(ofs_nbits,
880                        src,
881                        max_len)
882
883         def serialize_body(self):
884             data = bytearray()
885             src = bytearray()
886             oxm = ofp.oxm_from_user_header(self.src)
887             ofp.oxm_serialize_header(oxm, src, 0),
888             msg_pack_into(self._fmt_str, data, 0,
889                           self.ofs_nbits,
890                           six.binary_type(src),
891                           self.max_len)
892             return data
893
894     class NXActionOutputReg2(NXAction):
895         r"""
896         Add output action
897
898         This action outputs the packet to the OpenFlow port number read from
899         src.
900
901         And equivalent to the followings action of ovs-ofctl command.
902
903         ..
904           output:src[start...end]
905         ..
906
907         +-------------------------------------------------------+
908         | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
909         +-------------------------------------------------------+
910
911         .. NOTE::
912              Like the ``NXActionOutputReg`` but organized so
913              that there is room for a 64-bit experimenter OXM as 'src'.
914
915         ================ ======================================================
916         Attribute        Description
917         ================ ======================================================
918         ofs_nbits        Start and End for the OXM/NXM field.
919                          Setting method refer to the ``nicira_ext.ofs_nbits``
920         src              OXM/NXM header for source field
921         max_len          Max length to send to controller
922         ================ ======================================================
923
924         Example::
925
926             actions += [parser.NXActionOutputReg2(
927                             ofs_nbits=nicira_ext.ofs_nbits(4, 31),
928                             src="reg0",
929                             max_len=1024)]
930         """
931         _subtype = nicira_ext.NXAST_OUTPUT_REG2
932
933         # ofs_nbits, src, max_len
934         _fmt_str = '!HH4s'
935         _TYPE = {
936             'ascii': [
937                 'src',
938             ]
939         }
940
941         def __init__(self,
942                      ofs_nbits,
943                      src,
944                      max_len,
945                      type_=None, len_=None, experimenter=None, subtype=None):
946             super(NXActionOutputReg2, self).__init__()
947             self.ofs_nbits = ofs_nbits
948             self.src = src
949             self.max_len = max_len
950
951         @classmethod
952         def parser(cls, buf):
953             (ofs_nbits,
954              max_len,
955              oxm_data) = struct.unpack_from(
956                 cls._fmt_str, buf, 0)
957             (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
958             src = ofp.oxm_to_user_header(n)
959             return cls(ofs_nbits,
960                        src,
961                        max_len)
962
963         def serialize_body(self):
964             data = bytearray()
965             oxm_data = bytearray()
966             oxm = ofp.oxm_from_user_header(self.src)
967             ofp.oxm_serialize_header(oxm, oxm_data, 0),
968             msg_pack_into(self._fmt_str, data, 0,
969                           self.ofs_nbits,
970                           self.max_len,
971                           six.binary_type(oxm_data))
972             offset = len(data)
973             msg_pack_into("!%dx" % (14 - offset), data, offset)
974             return data
975
976     class NXActionLearn(NXAction):
977         r"""
978         Adds or modifies flow action
979
980         This action adds or modifies a flow in OpenFlow table.
981
982         And equivalent to the followings action of ovs-ofctl command.
983
984         ..
985           learn(argument[,argument]...)
986         ..
987
988         +---------------------------------------------------+
989         | **learn(**\ *argument*\[,\ *argument*\]...\ **)** |
990         +---------------------------------------------------+
991
992         ================ ======================================================
993         Attribute        Description
994         ================ ======================================================
995         table_id         The table in which the new flow should be inserted
996         specs            Adds a match criterion to the new flow
997
998                          Please use the
999                          ``NXFlowSpecMatch``
1000                          in order to set the following format
1001
1002                          ..
1003                            field=value
1004                            field[start..end]=src[start..end]
1005                            field[start..end]
1006                          ..
1007
1008                          | *field*\=\ *value*
1009                          | *field*\ **[**\ *start*\..\ *end*\ **]**\  =\
1010                          *src*\ **[**\ *start*\..\ *end*\ **]**
1011                          | *field*\ **[**\ *start*\..\ *end*\ **]**
1012                          |
1013
1014                          Please use the
1015                          ``NXFlowSpecLoad``
1016                          in order to set the following format
1017
1018                          ..
1019                            load:value->dst[start..end]
1020                            load:src[start..end]->dst[start..end]
1021                          ..
1022
1023                          | **load**\:\ *value*\ **->**\ *dst*\
1024                          **[**\ *start*\..\ *end*\ **]**
1025                          | **load**\:\ *src*\ **[**\ *start*\..\ *end*\
1026                          **] ->**\ *dst*\ **[**\ *start*\..\ *end*\ **]**
1027                          |
1028
1029                          Please use the
1030                          ``NXFlowSpecOutput``
1031                          in order to set the following format
1032
1033                          ..
1034                            output:field[start..end]
1035                          ..
1036
1037                          | **output:**\ field\ **[**\ *start*\..\ *end*\ **]**
1038
1039         idle_timeout     Idle time before discarding(seconds)
1040         hard_timeout     Max time before discarding(seconds)
1041         priority         Priority level of flow entry
1042         cookie           Cookie for new flow
1043         flags            send_flow_rem
1044         fin_idle_timeout Idle timeout after FIN(seconds)
1045         fin_hard_timeout Hard timeout after FIN(seconds)
1046         ================ ======================================================
1047
1048         .. CAUTION::
1049             The arguments specify the flow's match fields, actions,
1050             and other properties, as follows.
1051             At least one match criterion and one action argument
1052             should ordinarily be specified.
1053
1054         Example::
1055
1056             actions += [
1057                 parser.NXActionLearn(able_id=10,
1058                      specs=[parser.NXFlowSpecMatch(src=0x800,
1059                                                    dst=('eth_type_nxm', 0),
1060                                                    n_bits=16),
1061                             parser.NXFlowSpecMatch(src=('reg1', 1),
1062                                                    dst=('reg2', 3),
1063                                                    n_bits=5),
1064                             parser.NXFlowSpecMatch(src=('reg3', 1),
1065                                                    dst=('reg3', 1),
1066                                                    n_bits=5),
1067                             parser.NXFlowSpecLoad(src=0,
1068                                                   dst=('reg4', 3),
1069                                                   n_bits=5),
1070                             parser.NXFlowSpecLoad(src=('reg5', 1),
1071                                                   dst=('reg6', 3),
1072                                                   n_bits=5),
1073                             parser.NXFlowSpecOutput(src=('reg7', 1),
1074                                                     dst="",
1075                                                     n_bits=5)],
1076                      idle_timeout=180,
1077                      hard_timeout=300,
1078                      priority=1,
1079                      cookie=0x64,
1080                      flags=ofproto.OFPFF_SEND_FLOW_REM,
1081                      fin_idle_timeout=180,
1082                      fin_hard_timeout=300)]
1083         """
1084         _subtype = nicira_ext.NXAST_LEARN
1085
1086         # idle_timeout, hard_timeout, priority, cookie, flags,
1087         # table_id, pad, fin_idle_timeout, fin_hard_timeout
1088         _fmt_str = '!HHHQHBxHH'
1089         # Followed by flow_mod_specs
1090
1091         def __init__(self,
1092                      table_id,
1093                      specs,
1094                      idle_timeout=0,
1095                      hard_timeout=0,
1096                      priority=ofp.OFP_DEFAULT_PRIORITY,
1097                      cookie=0,
1098                      flags=0,
1099                      fin_idle_timeout=0,
1100                      fin_hard_timeout=0,
1101                      type_=None, len_=None, experimenter=None, subtype=None):
1102             super(NXActionLearn, self).__init__()
1103             self.idle_timeout = idle_timeout
1104             self.hard_timeout = hard_timeout
1105             self.priority = priority
1106             self.cookie = cookie
1107             self.flags = flags
1108             self.table_id = table_id
1109             self.fin_idle_timeout = fin_idle_timeout
1110             self.fin_hard_timeout = fin_hard_timeout
1111             self.specs = specs
1112
1113         @classmethod
1114         def parser(cls, buf):
1115             (idle_timeout,
1116              hard_timeout,
1117              priority,
1118              cookie,
1119              flags,
1120              table_id,
1121              fin_idle_timeout,
1122              fin_hard_timeout,) = struct.unpack_from(
1123                 cls._fmt_str, buf, 0)
1124             rest = buf[struct.calcsize(cls._fmt_str):]
1125             # specs
1126             specs = []
1127             while len(rest) > 0:
1128                 spec, rest = _NXFlowSpec.parse(rest)
1129                 if spec is None:
1130                     continue
1131                 specs.append(spec)
1132             return cls(idle_timeout=idle_timeout,
1133                        hard_timeout=hard_timeout,
1134                        priority=priority,
1135                        cookie=cookie,
1136                        flags=flags,
1137                        table_id=table_id,
1138                        fin_idle_timeout=fin_idle_timeout,
1139                        fin_hard_timeout=fin_hard_timeout,
1140                        specs=specs)
1141
1142         def serialize_body(self):
1143             # fixup
1144             data = bytearray()
1145             msg_pack_into(self._fmt_str, data, 0,
1146                           self.idle_timeout,
1147                           self.hard_timeout,
1148                           self.priority,
1149                           self.cookie,
1150                           self.flags,
1151                           self.table_id,
1152                           self.fin_idle_timeout,
1153                           self.fin_hard_timeout)
1154             for spec in self.specs:
1155                 data += spec.serialize()
1156             return data
1157
1158     class NXActionExit(NXAction):
1159         """
1160         Halt action
1161
1162         This action causes OpenvSwitch to immediately halt
1163         execution of further actions.
1164
1165         And equivalent to the followings action of ovs-ofctl command.
1166
1167         ..
1168           exit
1169         ..
1170
1171         +----------+
1172         | **exit** |
1173         +----------+
1174
1175         Example::
1176
1177             actions += [parser.NXActionExit()]
1178         """
1179         _subtype = nicira_ext.NXAST_EXIT
1180
1181         _fmt_str = '!6x'
1182
1183         def __init__(self,
1184                      type_=None, len_=None, experimenter=None, subtype=None):
1185             super(NXActionExit, self).__init__()
1186
1187         @classmethod
1188         def parser(cls, buf):
1189             return cls()
1190
1191         def serialize_body(self):
1192             data = bytearray()
1193             msg_pack_into(self._fmt_str, data, 0)
1194             return data
1195
1196     # For OpenFlow1.0 only
1197     class NXActionDecTtl(NXAction):
1198         """
1199         Decrement IP TTL action
1200
1201         This action decrements TTL of IPv4 packet or
1202         hop limit of IPv6 packet.
1203
1204         And equivalent to the followings action of ovs-ofctl command.
1205
1206         ..
1207           dec_ttl
1208         ..
1209
1210         +-------------+
1211         | **dec_ttl** |
1212         +-------------+
1213
1214         .. NOTE::
1215             This actions is supported by
1216             ``OFPActionDecNwTtl``
1217             in OpenFlow1.2 or later.
1218
1219         Example::
1220
1221             actions += [parser.NXActionDecTtl()]
1222         """
1223         _subtype = nicira_ext.NXAST_DEC_TTL
1224
1225         _fmt_str = '!6x'
1226
1227         def __init__(self,
1228                      type_=None, len_=None, vendor=None, subtype=None):
1229             super(NXActionDecTtl, self).__init__()
1230
1231         @classmethod
1232         def parser(cls, buf):
1233             return cls()
1234
1235         def serialize_body(self):
1236             data = bytearray()
1237             msg_pack_into(self._fmt_str, data, 0)
1238             return data
1239
1240     class NXActionController(NXAction):
1241         r"""
1242         Send packet in message action
1243
1244         This action sends the packet to the OpenFlow controller as
1245         a packet in message.
1246
1247         And equivalent to the followings action of ovs-ofctl command.
1248
1249         ..
1250           controller(key=value...)
1251         ..
1252
1253         +----------------------------------------------+
1254         | **controller(**\ *key*\=\ *value*\...\ **)** |
1255         +----------------------------------------------+
1256
1257         ================ ======================================================
1258         Attribute        Description
1259         ================ ======================================================
1260         max_len          Max length to send to controller
1261         controller_id    Controller ID to send packet-in
1262         reason           Reason for sending the message
1263         ================ ======================================================
1264
1265         Example::
1266
1267             actions += [
1268                 parser.NXActionController(max_len=1024,
1269                                           controller_id=1,
1270                                           reason=ofproto.OFPR_INVALID_TTL)]
1271         """
1272         _subtype = nicira_ext.NXAST_CONTROLLER
1273
1274         # max_len, controller_id, reason
1275         _fmt_str = '!HHBx'
1276
1277         def __init__(self,
1278                      max_len,
1279                      controller_id,
1280                      reason,
1281                      type_=None, len_=None, experimenter=None, subtype=None):
1282             super(NXActionController, self).__init__()
1283             self.max_len = max_len
1284             self.controller_id = controller_id
1285             self.reason = reason
1286
1287         @classmethod
1288         def parser(cls, buf):
1289             (max_len,
1290              controller_id,
1291              reason) = struct.unpack_from(
1292                 cls._fmt_str, buf)
1293             return cls(max_len,
1294                        controller_id,
1295                        reason)
1296
1297         def serialize_body(self):
1298             data = bytearray()
1299             msg_pack_into(self._fmt_str, data, 0,
1300                           self.max_len,
1301                           self.controller_id,
1302                           self.reason)
1303             return data
1304
1305     class NXActionController2(NXAction):
1306         r"""
1307         Send packet in message action
1308
1309         This action sends the packet to the OpenFlow controller as
1310         a packet in message.
1311
1312         And equivalent to the followings action of ovs-ofctl command.
1313
1314         ..
1315           controller(key=value...)
1316         ..
1317
1318         +----------------------------------------------+
1319         | **controller(**\ *key*\=\ *value*\...\ **)** |
1320         +----------------------------------------------+
1321
1322         ================ ======================================================
1323         Attribute        Description
1324         ================ ======================================================
1325         max_len          Max length to send to controller
1326         controller_id    Controller ID to send packet-in
1327         reason           Reason for sending the message
1328         userdata         Additional data to the controller in the packet-in
1329                          message
1330         pause            Flag to pause pipeline to resume later
1331         ================ ======================================================
1332
1333         Example::
1334
1335             actions += [
1336                 parser.NXActionController(max_len=1024,
1337                                           controller_id=1,
1338                                           reason=ofproto.OFPR_INVALID_TTL,
1339                                           userdata=[0xa,0xb,0xc],
1340                                           pause=True)]
1341         """
1342         _subtype = nicira_ext.NXAST_CONTROLLER2
1343         _fmt_str = '!6x'
1344         _PACK_STR = '!HH'
1345
1346         def __init__(self,
1347                      type_=None, len_=None, vendor=None, subtype=None,
1348                      **kwargs):
1349             super(NXActionController2, self).__init__()
1350
1351             for arg in kwargs:
1352                 if arg in NXActionController2Prop._NAMES:
1353                     setattr(self, arg, kwargs[arg])
1354
1355         @classmethod
1356         def parser(cls, buf):
1357             cls_data = {}
1358             offset = 6
1359             buf_len = len(buf)
1360             while buf_len > offset:
1361                 (type_, length) = struct.unpack_from(cls._PACK_STR, buf, offset)
1362                 offset += 4
1363                 try:
1364                     subcls = NXActionController2Prop._TYPES[type_]
1365                 except KeyError:
1366                     subcls = NXActionController2PropUnknown
1367                 data, size = subcls.parser_prop(buf[offset:], length - 4)
1368                 offset += size
1369                 cls_data[subcls._arg_name] = data
1370             return cls(**cls_data)
1371
1372         def serialize_body(self):
1373             body = bytearray()
1374             msg_pack_into(self._fmt_str, body, 0)
1375             prop_list = []
1376             for arg in self.__dict__:
1377                 if arg in NXActionController2Prop._NAMES:
1378                     prop_list.append((NXActionController2Prop._NAMES[arg],
1379                                       self.__dict__[arg]))
1380             prop_list.sort(key=lambda x: x[0].type)
1381
1382             for subcls, value in prop_list:
1383                 body += subcls.serialize_prop(value)
1384
1385             return body
1386
1387     class NXActionController2Prop(object):
1388         _TYPES = {}
1389         _NAMES = {}
1390
1391         @classmethod
1392         def register_type(cls, type_):
1393             def _register_type(subcls):
1394                 subcls.type = type_
1395                 NXActionController2Prop._TYPES[type_] = subcls
1396                 NXActionController2Prop._NAMES[subcls._arg_name] = subcls
1397                 return subcls
1398
1399             return _register_type
1400
1401     class NXActionController2PropUnknown(NXActionController2Prop):
1402
1403         @classmethod
1404         def parser_prop(cls, buf, length):
1405             size = 4
1406             return buf, size
1407
1408         @classmethod
1409         def serialize_prop(cls, argment):
1410             data = bytearray()
1411             return data
1412
1413     @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_MAX_LEN)
1414     class NXActionController2PropMaxLen(NXActionController2Prop):
1415         # max_len
1416         _fmt_str = "!H2x"
1417         _arg_name = "max_len"
1418
1419         @classmethod
1420         def parser_prop(cls, buf, length):
1421             size = 4
1422             (max_len,) = struct.unpack_from(
1423                 cls._fmt_str, buf, 0)
1424             return max_len, size
1425
1426         @classmethod
1427         def serialize_prop(cls, max_len):
1428             data = bytearray()
1429             msg_pack_into("!HHH2x", data, 0,
1430                           nicira_ext.NXAC2PT_MAX_LEN,
1431                           8,
1432                           max_len)
1433             return data
1434
1435     @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_CONTROLLER_ID)
1436     class NXActionController2PropControllerId(NXActionController2Prop):
1437         # controller_id
1438         _fmt_str = "!H2x"
1439         _arg_name = "controller_id"
1440
1441         @classmethod
1442         def parser_prop(cls, buf, length):
1443             size = 4
1444             (controller_id,) = struct.unpack_from(
1445                 cls._fmt_str, buf, 0)
1446             return controller_id, size
1447
1448         @classmethod
1449         def serialize_prop(cls, controller_id):
1450             data = bytearray()
1451             msg_pack_into("!HHH2x", data, 0,
1452                           nicira_ext.NXAC2PT_CONTROLLER_ID,
1453                           8,
1454                           controller_id)
1455             return data
1456
1457     @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_REASON)
1458     class NXActionController2PropReason(NXActionController2Prop):
1459         # reason
1460         _fmt_str = "!B3x"
1461         _arg_name = "reason"
1462
1463         @classmethod
1464         def parser_prop(cls, buf, length):
1465             size = 4
1466             (reason,) = struct.unpack_from(
1467                 cls._fmt_str, buf, 0)
1468             return reason, size
1469
1470         @classmethod
1471         def serialize_prop(cls, reason):
1472             data = bytearray()
1473             msg_pack_into("!HHB3x", data, 0,
1474                           nicira_ext.NXAC2PT_REASON,
1475                           5,
1476                           reason)
1477             return data
1478
1479     @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_USERDATA)
1480     class NXActionController2PropUserData(NXActionController2Prop):
1481         # userdata
1482         _fmt_str = "!B"
1483         _arg_name = "userdata"
1484
1485         @classmethod
1486         def parser_prop(cls, buf, length):
1487             userdata = []
1488             offset = 0
1489
1490             while offset < length:
1491                 u = struct.unpack_from(cls._fmt_str, buf, offset)
1492                 userdata.append(u[0])
1493                 offset += 1
1494
1495             user_size = utils.round_up(length, 4)
1496
1497             if user_size > 4 and (user_size % 8) == 0:
1498                 size = utils.round_up(length, 4) + 4
1499             else:
1500                 size = utils.round_up(length, 4)
1501
1502             return userdata, size
1503
1504         @classmethod
1505         def serialize_prop(cls, userdata):
1506             data = bytearray()
1507             user_buf = bytearray()
1508             user_offset = 0
1509             for user in userdata:
1510                 msg_pack_into('!B', user_buf, user_offset,
1511                               user)
1512                 user_offset += 1
1513
1514             msg_pack_into("!HH", data, 0,
1515                           nicira_ext.NXAC2PT_USERDATA,
1516                           4 + user_offset)
1517             data += user_buf
1518
1519             if user_offset > 4:
1520                 user_len = utils.round_up(user_offset, 4)
1521                 brank_size = 0
1522                 if (user_len % 8) == 0:
1523                     brank_size = 4
1524                 msg_pack_into("!%dx" % (user_len - user_offset + brank_size),
1525                               data, 4 + user_offset)
1526             else:
1527                 user_len = utils.round_up(user_offset, 4)
1528
1529                 msg_pack_into("!%dx" % (user_len - user_offset),
1530                               data, 4 + user_offset)
1531             return data
1532
1533     @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_PAUSE)
1534     class NXActionController2PropPause(NXActionController2Prop):
1535         _arg_name = "pause"
1536
1537         @classmethod
1538         def parser_prop(cls, buf, length):
1539             pause = True
1540             size = 4
1541             return pause, size
1542
1543         @classmethod
1544         def serialize_prop(cls, pause):
1545             data = bytearray()
1546             msg_pack_into("!HH4x", data, 0,
1547                           nicira_ext.NXAC2PT_PAUSE,
1548                           4)
1549             return data
1550
1551     class NXActionDecTtlCntIds(NXAction):
1552         r"""
1553         Decrement TTL action
1554
1555         This action decrements TTL of IPv4 packet or
1556         hop limits of IPv6 packet.
1557
1558         And equivalent to the followings action of ovs-ofctl command.
1559
1560         ..
1561           dec_ttl(id1[,id2]...)
1562         ..
1563
1564         +-------------------------------------------+
1565         | **dec_ttl(**\ *id1*\[,\ *id2*\]...\ **)** |
1566         +-------------------------------------------+
1567
1568         ================ ======================================================
1569         Attribute        Description
1570         ================ ======================================================
1571         cnt_ids          Controller ids
1572         ================ ======================================================
1573
1574         Example::
1575
1576             actions += [parser.NXActionDecTtlCntIds(cnt_ids=[1,2,3])]
1577
1578         .. NOTE::
1579             If you want to set the following ovs-ofctl command.
1580             Please use ``OFPActionDecNwTtl``.
1581
1582         +-------------+
1583         | **dec_ttl** |
1584         +-------------+
1585         """
1586         _subtype = nicira_ext.NXAST_DEC_TTL_CNT_IDS
1587
1588         # controllers
1589         _fmt_str = '!H4x'
1590         _fmt_len = 6
1591
1592         def __init__(self,
1593                      cnt_ids,
1594                      type_=None, len_=None, experimenter=None, subtype=None):
1595             super(NXActionDecTtlCntIds, self).__init__()
1596
1597             self.cnt_ids = cnt_ids
1598
1599         @classmethod
1600         def parser(cls, buf):
1601             (controllers,) = struct.unpack_from(
1602                 cls._fmt_str, buf)
1603
1604             offset = cls._fmt_len
1605             cnt_ids = []
1606
1607             for i in range(0, controllers):
1608                 id_ = struct.unpack_from('!H', buf, offset)
1609                 cnt_ids.append(id_[0])
1610                 offset += 2
1611
1612             return cls(cnt_ids)
1613
1614         def serialize_body(self):
1615             assert isinstance(self.cnt_ids, (tuple, list))
1616             for i in self.cnt_ids:
1617                 assert isinstance(i, six.integer_types)
1618
1619             controllers = len(self.cnt_ids)
1620
1621             data = bytearray()
1622             msg_pack_into(self._fmt_str, data, 0,
1623                           controllers)
1624             offset = self._fmt_len
1625
1626             for id_ in self.cnt_ids:
1627                 msg_pack_into('!H', data, offset, id_)
1628                 offset += 2
1629
1630             id_len = (utils.round_up(controllers, 4) -
1631                       controllers)
1632
1633             if id_len != 0:
1634                 msg_pack_into('%dx' % id_len * 2, data, offset)
1635
1636             return data
1637
1638     # Use in only OpenFlow1.0
1639     class NXActionMplsBase(NXAction):
1640         # ethertype
1641         _fmt_str = '!H4x'
1642
1643         def __init__(self,
1644                      ethertype,
1645                      type_=None, len_=None, vendor=None, subtype=None):
1646             super(NXActionMplsBase, self).__init__()
1647             self.ethertype = ethertype
1648
1649         @classmethod
1650         def parser(cls, buf):
1651             (ethertype,) = struct.unpack_from(
1652                 cls._fmt_str, buf)
1653             return cls(ethertype)
1654
1655         def serialize_body(self):
1656             data = bytearray()
1657             msg_pack_into(self._fmt_str, data, 0,
1658                           self.ethertype)
1659             return data
1660
1661     # For OpenFlow1.0 only
1662     class NXActionPushMpls(NXActionMplsBase):
1663         r"""
1664         Push MPLS action
1665
1666         This action pushes a new MPLS header to the packet.
1667
1668         And equivalent to the followings action of ovs-ofctl command.
1669
1670         ..
1671           push_mpls:ethertype
1672         ..
1673
1674         +-------------------------------+
1675         | **push_mpls**\:\ *ethertype*  |
1676         +-------------------------------+
1677
1678         ================ ======================================================
1679         Attribute        Description
1680         ================ ======================================================
1681         ethertype        Ether type(The value must be either 0x8847 or 0x8848)
1682         ================ ======================================================
1683
1684         .. NOTE::
1685             This actions is supported by
1686             ``OFPActionPushMpls``
1687             in OpenFlow1.2 or later.
1688
1689         Example::
1690
1691             match = parser.OFPMatch(dl_type=0x0800)
1692             actions += [parser.NXActionPushMpls(ethertype=0x8847)]
1693         """
1694         _subtype = nicira_ext.NXAST_PUSH_MPLS
1695
1696     # For OpenFlow1.0 only
1697     class NXActionPopMpls(NXActionMplsBase):
1698         r"""
1699         Pop MPLS action
1700
1701         This action pops the MPLS header from the packet.
1702
1703         And equivalent to the followings action of ovs-ofctl command.
1704
1705         ..
1706           pop_mpls:ethertype
1707         ..
1708
1709         +------------------------------+
1710         | **pop_mpls**\:\ *ethertype*  |
1711         +------------------------------+
1712
1713         ================ ======================================================
1714         Attribute        Description
1715         ================ ======================================================
1716         ethertype        Ether type
1717         ================ ======================================================
1718
1719         .. NOTE::
1720             This actions is supported by
1721             ``OFPActionPopMpls``
1722             in OpenFlow1.2 or later.
1723
1724         Example::
1725
1726             match = parser.OFPMatch(dl_type=0x8847)
1727             actions += [parser.NXActionPushMpls(ethertype=0x0800)]
1728         """
1729         _subtype = nicira_ext.NXAST_POP_MPLS
1730
1731     # For OpenFlow1.0 only
1732     class NXActionSetMplsTtl(NXAction):
1733         r"""
1734         Set MPLS TTL action
1735
1736         This action sets the MPLS TTL.
1737
1738         And equivalent to the followings action of ovs-ofctl command.
1739
1740         ..
1741           set_mpls_ttl:ttl
1742         ..
1743
1744         +---------------------------+
1745         | **set_mpls_ttl**\:\ *ttl* |
1746         +---------------------------+
1747
1748         ================ ======================================================
1749         Attribute        Description
1750         ================ ======================================================
1751         ttl              MPLS TTL
1752         ================ ======================================================
1753
1754         .. NOTE::
1755             This actions is supported by
1756             ``OFPActionSetMplsTtl``
1757             in OpenFlow1.2 or later.
1758
1759         Example::
1760
1761             actions += [parser.NXActionSetMplsTil(ttl=128)]
1762         """
1763         _subtype = nicira_ext.NXAST_SET_MPLS_TTL
1764
1765         # ethertype
1766         _fmt_str = '!B5x'
1767
1768         def __init__(self,
1769                      ttl,
1770                      type_=None, len_=None, vendor=None, subtype=None):
1771             super(NXActionSetMplsTtl, self).__init__()
1772             self.ttl = ttl
1773
1774         @classmethod
1775         def parser(cls, buf):
1776             (ttl,) = struct.unpack_from(
1777                 cls._fmt_str, buf)
1778             return cls(ttl)
1779
1780         def serialize_body(self):
1781             data = bytearray()
1782             msg_pack_into(self._fmt_str, data, 0,
1783                           self.ttl)
1784             return data
1785
1786     # For OpenFlow1.0 only
1787     class NXActionDecMplsTtl(NXAction):
1788         """
1789         Decrement MPLS TTL action
1790
1791         This action decrements the MPLS TTL.
1792
1793         And equivalent to the followings action of ovs-ofctl command.
1794
1795         ..
1796           dec_mpls_ttl
1797         ..
1798
1799         +------------------+
1800         | **dec_mpls_ttl** |
1801         +------------------+
1802
1803         .. NOTE::
1804             This actions is supported by
1805             ``OFPActionDecMplsTtl``
1806             in OpenFlow1.2 or later.
1807
1808         Example::
1809
1810             actions += [parser.NXActionDecMplsTil()]
1811         """
1812         _subtype = nicira_ext.NXAST_DEC_MPLS_TTL
1813
1814         # ethertype
1815         _fmt_str = '!6x'
1816
1817         def __init__(self,
1818                      type_=None, len_=None, vendor=None, subtype=None):
1819             super(NXActionDecMplsTtl, self).__init__()
1820
1821         @classmethod
1822         def parser(cls, buf):
1823             return cls()
1824
1825         def serialize_body(self):
1826             data = bytearray()
1827             msg_pack_into(self._fmt_str, data, 0)
1828             return data
1829
1830     # For OpenFlow1.0 only
1831     class NXActionSetMplsLabel(NXAction):
1832         r"""
1833         Set MPLS Lavel action
1834
1835         This action sets the MPLS Label.
1836
1837         And equivalent to the followings action of ovs-ofctl command.
1838
1839         ..
1840           set_mpls_label:label
1841         ..
1842
1843         +-------------------------------+
1844         | **set_mpls_label**\:\ *label* |
1845         +-------------------------------+
1846
1847         ================ ======================================================
1848         Attribute        Description
1849         ================ ======================================================
1850         label            MPLS Label
1851         ================ ======================================================
1852
1853         .. NOTE::
1854             This actions is supported by
1855             ``OFPActionSetField(mpls_label=label)``
1856             in OpenFlow1.2 or later.
1857
1858         Example::
1859
1860             actions += [parser.NXActionSetMplsLabel(label=0x10)]
1861         """
1862         _subtype = nicira_ext.NXAST_SET_MPLS_LABEL
1863
1864         # ethertype
1865         _fmt_str = '!2xI'
1866
1867         def __init__(self,
1868                      label,
1869                      type_=None, len_=None, vendor=None, subtype=None):
1870             super(NXActionSetMplsLabel, self).__init__()
1871             self.label = label
1872
1873         @classmethod
1874         def parser(cls, buf):
1875             (label,) = struct.unpack_from(
1876                 cls._fmt_str, buf)
1877             return cls(label)
1878
1879         def serialize_body(self):
1880             data = bytearray()
1881             msg_pack_into(self._fmt_str, data, 0,
1882                           self.label)
1883             return data
1884
1885     # For OpenFlow1.0 only
1886     class NXActionSetMplsTc(NXAction):
1887         r"""
1888         Set MPLS Tc action
1889
1890         This action sets the MPLS Tc.
1891
1892         And equivalent to the followings action of ovs-ofctl command.
1893
1894         ..
1895           set_mpls_tc:tc
1896         ..
1897
1898         +-------------------------+
1899         | **set_mpls_tc**\:\ *tc* |
1900         +-------------------------+
1901
1902         ================ ======================================================
1903         Attribute        Description
1904         ================ ======================================================
1905         tc               MPLS Tc
1906         ================ ======================================================
1907
1908         .. NOTE::
1909             This actions is supported by
1910             ``OFPActionSetField(mpls_label=tc)``
1911             in OpenFlow1.2 or later.
1912
1913         Example::
1914
1915             actions += [parser.NXActionSetMplsLabel(tc=0x10)]
1916         """
1917         _subtype = nicira_ext.NXAST_SET_MPLS_TC
1918
1919         # ethertype
1920         _fmt_str = '!B5x'
1921
1922         def __init__(self,
1923                      tc,
1924                      type_=None, len_=None, vendor=None, subtype=None):
1925             super(NXActionSetMplsTc, self).__init__()
1926             self.tc = tc
1927
1928         @classmethod
1929         def parser(cls, buf):
1930             (tc,) = struct.unpack_from(
1931                 cls._fmt_str, buf)
1932             return cls(tc)
1933
1934         def serialize_body(self):
1935             data = bytearray()
1936             msg_pack_into(self._fmt_str, data, 0,
1937                           self.tc)
1938             return data
1939
1940     class NXActionStackBase(NXAction):
1941         # start, field, end
1942         _fmt_str = '!H4sH'
1943         _TYPE = {
1944             'ascii': [
1945                 'field',
1946             ]
1947         }
1948
1949         def __init__(self,
1950                      field,
1951                      start,
1952                      end,
1953                      type_=None, len_=None, experimenter=None, subtype=None):
1954             super(NXActionStackBase, self).__init__()
1955             self.field = field
1956             self.start = start
1957             self.end = end
1958
1959         @classmethod
1960         def parser(cls, buf):
1961             (start, oxm_data, end) = struct.unpack_from(
1962                 cls._fmt_str, buf, 0)
1963             (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
1964             field = ofp.oxm_to_user_header(n)
1965             return cls(field, start, end)
1966
1967         def serialize_body(self):
1968             data = bytearray()
1969             oxm_data = bytearray()
1970             oxm = ofp.oxm_from_user_header(self.field)
1971             ofp.oxm_serialize_header(oxm, oxm_data, 0)
1972             msg_pack_into(self._fmt_str, data, 0,
1973                           self.start,
1974                           six.binary_type(oxm_data),
1975                           self.end)
1976             offset = len(data)
1977             msg_pack_into("!%dx" % (12 - offset), data, offset)
1978             return data
1979
1980     class NXActionStackPush(NXActionStackBase):
1981         r"""
1982         Push field action
1983
1984         This action pushes field to top of the stack.
1985
1986         And equivalent to the followings action of ovs-ofctl command.
1987
1988         ..
1989           pop:dst[start...end]
1990         ..
1991
1992         +----------------------------------------------------+
1993         | **pop**\:\ *dst*\ **[**\ *start*\...\ *end*\ **]** |
1994         +----------------------------------------------------+
1995
1996         ================ ======================================================
1997         Attribute        Description
1998         ================ ======================================================
1999         field            OXM/NXM header for source field
2000         start            Start bit for source field
2001         end              End bit for source field
2002         ================ ======================================================
2003
2004         Example::
2005
2006             actions += [parser.NXActionStackPush(field="reg2",
2007                                                  start=0,
2008                                                  end=5)]
2009         """
2010         _subtype = nicira_ext.NXAST_STACK_PUSH
2011
2012     class NXActionStackPop(NXActionStackBase):
2013         r"""
2014         Pop field action
2015
2016         This action pops field from top of the stack.
2017
2018         And equivalent to the followings action of ovs-ofctl command.
2019
2020         ..
2021           pop:src[start...end]
2022         ..
2023
2024         +----------------------------------------------------+
2025         | **pop**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
2026         +----------------------------------------------------+
2027
2028         ================ ======================================================
2029         Attribute        Description
2030         ================ ======================================================
2031         field            OXM/NXM header for destination field
2032         start            Start bit for destination field
2033         end              End bit for destination field
2034         ================ ======================================================
2035
2036         Example::
2037
2038             actions += [parser.NXActionStackPop(field="reg2",
2039                                                 start=0,
2040                                                 end=5)]
2041         """
2042         _subtype = nicira_ext.NXAST_STACK_POP
2043
2044     class NXActionSample(NXAction):
2045         r"""
2046         Sample packets action
2047
2048         This action samples packets and sends one sample for
2049         every sampled packet.
2050
2051         And equivalent to the followings action of ovs-ofctl command.
2052
2053         ..
2054           sample(argument[,argument]...)
2055         ..
2056
2057         +----------------------------------------------------+
2058         | **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
2059         +----------------------------------------------------+
2060
2061         ================ ======================================================
2062         Attribute        Description
2063         ================ ======================================================
2064         probability      The number of sampled packets
2065         collector_set_id The unsigned 32-bit integer identifier of
2066                          the set of sample collectors to send sampled packets
2067                          to
2068         obs_domain_id    The Unsigned 32-bit integer Observation Domain ID
2069         obs_point_id     The unsigned 32-bit integer Observation Point ID
2070         ================ ======================================================
2071
2072         Example::
2073
2074             actions += [parser.NXActionSample(probability=3,
2075                                               collector_set_id=1,
2076                                               obs_domain_id=2,
2077                                               obs_point_id=3,)]
2078         """
2079         _subtype = nicira_ext.NXAST_SAMPLE
2080
2081         # probability, collector_set_id, obs_domain_id, obs_point_id
2082         _fmt_str = '!HIII'
2083
2084         def __init__(self,
2085                      probability,
2086                      collector_set_id=0,
2087                      obs_domain_id=0,
2088                      obs_point_id=0,
2089                      type_=None, len_=None, experimenter=None, subtype=None):
2090             super(NXActionSample, self).__init__()
2091             self.probability = probability
2092             self.collector_set_id = collector_set_id
2093             self.obs_domain_id = obs_domain_id
2094             self.obs_point_id = obs_point_id
2095
2096         @classmethod
2097         def parser(cls, buf):
2098             (probability,
2099              collector_set_id,
2100              obs_domain_id,
2101              obs_point_id) = struct.unpack_from(
2102                 cls._fmt_str, buf, 0)
2103             return cls(probability,
2104                        collector_set_id,
2105                        obs_domain_id,
2106                        obs_point_id)
2107
2108         def serialize_body(self):
2109             data = bytearray()
2110             msg_pack_into(self._fmt_str, data, 0,
2111                           self.probability,
2112                           self.collector_set_id,
2113                           self.obs_domain_id,
2114                           self.obs_point_id)
2115             return data
2116
2117     class NXActionSample2(NXAction):
2118         r"""
2119         Sample packets action
2120
2121         This action samples packets and sends one sample for
2122         every sampled packet.
2123         'sampling_port' can be equal to ingress port or one of egress ports.
2124
2125         And equivalent to the followings action of ovs-ofctl command.
2126
2127         ..
2128           sample(argument[,argument]...)
2129         ..
2130
2131         +----------------------------------------------------+
2132         | **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
2133         +----------------------------------------------------+
2134
2135         ================ ======================================================
2136         Attribute        Description
2137         ================ ======================================================
2138         probability      The number of sampled packets
2139         collector_set_id The unsigned 32-bit integer identifier of
2140                          the set of sample collectors to send sampled packets to
2141         obs_domain_id    The Unsigned 32-bit integer Observation Domain ID
2142         obs_point_id     The unsigned 32-bit integer Observation Point ID
2143         sampling_port    Sampling port number
2144         ================ ======================================================
2145
2146         Example::
2147
2148             actions += [parser.NXActionSample2(probability=3,
2149                                                collector_set_id=1,
2150                                                obs_domain_id=2,
2151                                                obs_point_id=3,
2152                                                sampling_port=8080)]
2153         """
2154         _subtype = nicira_ext.NXAST_SAMPLE2
2155
2156         # probability, collector_set_id, obs_domain_id,
2157         # obs_point_id, sampling_port
2158         _fmt_str = '!HIIIH6x'
2159
2160         def __init__(self,
2161                      probability,
2162                      collector_set_id=0,
2163                      obs_domain_id=0,
2164                      obs_point_id=0,
2165                      sampling_port=0,
2166                      type_=None, len_=None, experimenter=None, subtype=None):
2167             super(NXActionSample2, self).__init__()
2168             self.probability = probability
2169             self.collector_set_id = collector_set_id
2170             self.obs_domain_id = obs_domain_id
2171             self.obs_point_id = obs_point_id
2172             self.sampling_port = sampling_port
2173
2174         @classmethod
2175         def parser(cls, buf):
2176             (probability,
2177              collector_set_id,
2178              obs_domain_id,
2179              obs_point_id,
2180              sampling_port) = struct.unpack_from(
2181                 cls._fmt_str, buf, 0)
2182             return cls(probability,
2183                        collector_set_id,
2184                        obs_domain_id,
2185                        obs_point_id,
2186                        sampling_port)
2187
2188         def serialize_body(self):
2189             data = bytearray()
2190             msg_pack_into(self._fmt_str, data, 0,
2191                           self.probability,
2192                           self.collector_set_id,
2193                           self.obs_domain_id,
2194                           self.obs_point_id,
2195                           self.sampling_port)
2196             return data
2197
2198     class NXActionFinTimeout(NXAction):
2199         r"""
2200         Change TCP timeout action
2201
2202         This action changes the idle timeout or hard timeout or
2203         both, of this OpenFlow rule when the rule matches a TCP
2204         packet with the FIN or RST flag.
2205
2206         And equivalent to the followings action of ovs-ofctl command.
2207
2208         ..
2209           fin_timeout(argument[,argument]...)
2210         ..
2211
2212         +---------------------------------------------------------+
2213         | **fin_timeout(**\ *argument*\[,\ *argument*\]...\ **)** |
2214         +---------------------------------------------------------+
2215
2216         ================ ======================================================
2217         Attribute        Description
2218         ================ ======================================================
2219         fin_idle_timeout Causes the flow to expire after the given number
2220                          of seconds of inactivity
2221         fin_idle_timeout Causes the flow to expire after the given number
2222                          of second, regardless of activity
2223         ================ ======================================================
2224
2225         Example::
2226
2227             match = parser.OFPMatch(ip_proto=6, eth_type=0x0800)
2228             actions += [parser.NXActionFinTimeout(fin_idle_timeout=30,
2229                                                   fin_hard_timeout=60)]
2230         """
2231         _subtype = nicira_ext.NXAST_FIN_TIMEOUT
2232
2233         # fin_idle_timeout, fin_hard_timeout
2234         _fmt_str = '!HH2x'
2235
2236         def __init__(self,
2237                      fin_idle_timeout,
2238                      fin_hard_timeout,
2239                      type_=None, len_=None, experimenter=None, subtype=None):
2240             super(NXActionFinTimeout, self).__init__()
2241             self.fin_idle_timeout = fin_idle_timeout
2242             self.fin_hard_timeout = fin_hard_timeout
2243
2244         @classmethod
2245         def parser(cls, buf):
2246             (fin_idle_timeout,
2247              fin_hard_timeout) = struct.unpack_from(
2248                 cls._fmt_str, buf, 0)
2249             return cls(fin_idle_timeout,
2250                        fin_hard_timeout)
2251
2252         def serialize_body(self):
2253             data = bytearray()
2254             msg_pack_into(self._fmt_str, data, 0,
2255                           self.fin_idle_timeout,
2256                           self.fin_hard_timeout)
2257             return data
2258
2259     class NXActionConjunction(NXAction):
2260         r"""
2261         Conjunctive matches action
2262
2263         This action ties groups of individual OpenFlow flows into
2264         higher-level conjunctive flows.
2265         Please refer to the ovs-ofctl command manual for details.
2266
2267         And equivalent to the followings action of ovs-ofctl command.
2268
2269         ..
2270           conjunction(id,k/n)
2271         ..
2272
2273         +--------------------------------------------------+
2274         | **conjunction(**\ *id*\,\ *k*\ **/**\ *n*\ **)** |
2275         +--------------------------------------------------+
2276
2277         ================ ======================================================
2278         Attribute        Description
2279         ================ ======================================================
2280         clause           Number assigned to the flow's dimension
2281         n_clauses        Specify the conjunctive flow's match condition
2282         id\_             Conjunction ID
2283         ================ ======================================================
2284
2285         Example::
2286
2287             actions += [parser.NXActionConjunction(clause=1,
2288                                                    n_clauses=2,
2289                                                    id_=10)]
2290         """
2291         _subtype = nicira_ext.NXAST_CONJUNCTION
2292
2293         # clause, n_clauses, id
2294         _fmt_str = '!BBI'
2295
2296         def __init__(self,
2297                      clause,
2298                      n_clauses,
2299                      id_,
2300                      type_=None, len_=None, experimenter=None, subtype=None):
2301             super(NXActionConjunction, self).__init__()
2302             self.clause = clause
2303             self.n_clauses = n_clauses
2304             self.id = id_
2305
2306         @classmethod
2307         def parser(cls, buf):
2308             (clause,
2309              n_clauses,
2310              id_,) = struct.unpack_from(
2311                 cls._fmt_str, buf, 0)
2312             return cls(clause, n_clauses, id_)
2313
2314         def serialize_body(self):
2315             data = bytearray()
2316             msg_pack_into(self._fmt_str, data, 0,
2317                           self.clause,
2318                           self.n_clauses,
2319                           self.id)
2320             return data
2321
2322     class NXActionMultipath(NXAction):
2323         r"""
2324         Select multipath link action
2325
2326         This action selects multipath link based on the specified parameters.
2327         Please refer to the ovs-ofctl command manual for details.
2328
2329         And equivalent to the followings action of ovs-ofctl command.
2330
2331         ..
2332           multipath(fields, basis, algorithm, n_links, arg, dst[start..end])
2333         ..
2334
2335         +-------------------------------------------------------------+
2336         | **multipath(**\ *fields*\, \ *basis*\, \ *algorithm*\,      |
2337         | *n_links*\, \ *arg*\, \ *dst*\[\ *start*\..\ *end*\]\ **)** |
2338         +-------------------------------------------------------------+
2339
2340         ================ ======================================================
2341         Attribute        Description
2342         ================ ======================================================
2343         fields           One of NX_HASH_FIELDS_*
2344         basis            Universal hash parameter
2345         algorithm        One of NX_MP_ALG_*.
2346         max_link         Number of output links
2347         arg              Algorithm-specific argument
2348         ofs_nbits        Start and End for the OXM/NXM field.
2349                          Setting method refer to the ``nicira_ext.ofs_nbits``
2350         dst              OXM/NXM header for source field
2351         ================ ======================================================
2352
2353         Example::
2354
2355             actions += [parser.NXActionMultipath(
2356                             fields=nicira_ext.NX_HASH_FIELDS_SYMMETRIC_L4,
2357                             basis=1024,
2358                             algorithm=nicira_ext.NX_MP_ALG_HRW,
2359                             max_link=5,
2360                             arg=0,
2361                             ofs_nbits=nicira_ext.ofs_nbits(4, 31),
2362                             dst="reg2")]
2363         """
2364         _subtype = nicira_ext.NXAST_MULTIPATH
2365
2366         # fields, basis, algorithm, max_link,
2367         # arg, ofs_nbits, dst
2368         _fmt_str = '!HH2xHHI2xH4s'
2369         _TYPE = {
2370             'ascii': [
2371                 'dst',
2372             ]
2373         }
2374
2375         def __init__(self,
2376                      fields,
2377                      basis,
2378                      algorithm,
2379                      max_link,
2380                      arg,
2381                      ofs_nbits,
2382                      dst,
2383                      type_=None, len_=None, experimenter=None, subtype=None):
2384             super(NXActionMultipath, self).__init__()
2385             self.fields = fields
2386             self.basis = basis
2387             self.algorithm = algorithm
2388             self.max_link = max_link
2389             self.arg = arg
2390             self.ofs_nbits = ofs_nbits
2391             self.dst = dst
2392
2393         @classmethod
2394         def parser(cls, buf):
2395             (fields,
2396              basis,
2397              algorithm,
2398              max_link,
2399              arg,
2400              ofs_nbits,
2401              oxm_data) = struct.unpack_from(
2402                 cls._fmt_str, buf, 0)
2403             (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
2404             dst = ofp.oxm_to_user_header(n)
2405             return cls(fields,
2406                        basis,
2407                        algorithm,
2408                        max_link,
2409                        arg,
2410                        ofs_nbits,
2411                        dst)
2412
2413         def serialize_body(self):
2414             data = bytearray()
2415             dst = bytearray()
2416             oxm = ofp.oxm_from_user_header(self.dst)
2417             ofp.oxm_serialize_header(oxm, dst, 0),
2418             msg_pack_into(self._fmt_str, data, 0,
2419                           self.fields,
2420                           self.basis,
2421                           self.algorithm,
2422                           self.max_link,
2423                           self.arg,
2424                           self.ofs_nbits,
2425                           six.binary_type(dst))
2426
2427             return data
2428
2429     class _NXActionBundleBase(NXAction):
2430         # algorithm, fields, basis, slave_type, n_slaves
2431         # ofs_nbits
2432         _fmt_str = '!HHHIHH'
2433
2434         def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
2435                      ofs_nbits, dst, slaves):
2436             super(_NXActionBundleBase, self).__init__()
2437             self.len = utils.round_up(
2438                 nicira_ext.NX_ACTION_BUNDLE_0_SIZE + len(slaves) * 2, 8)
2439
2440             self.algorithm = algorithm
2441             self.fields = fields
2442             self.basis = basis
2443             self.slave_type = slave_type
2444             self.n_slaves = n_slaves
2445             self.ofs_nbits = ofs_nbits
2446             self.dst = dst
2447
2448             assert isinstance(slaves, (list, tuple))
2449             for s in slaves:
2450                 assert isinstance(s, six.integer_types)
2451
2452             self.slaves = slaves
2453
2454         @classmethod
2455         def parser(cls, buf):
2456             # Add dst ('I') to _fmt_str
2457             (algorithm, fields, basis,
2458              slave_type, n_slaves, ofs_nbits, dst) = struct.unpack_from(
2459                 cls._fmt_str + 'I', buf, 0)
2460
2461             offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
2462                       nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
2463
2464             if dst != 0:
2465                 (n, len_) = ofp.oxm_parse_header(buf, offset)
2466                 dst = ofp.oxm_to_user_header(n)
2467
2468             slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
2469                             nicira_ext.NX_ACTION_HEADER_0_SIZE)
2470
2471             slaves = []
2472             for i in range(0, n_slaves):
2473                 s = struct.unpack_from('!H', buf, slave_offset)
2474                 slaves.append(s[0])
2475                 slave_offset += 2
2476
2477             return cls(algorithm, fields, basis, slave_type,
2478                        n_slaves, ofs_nbits, dst, slaves)
2479
2480         def serialize_body(self):
2481             data = bytearray()
2482             slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
2483                             nicira_ext.NX_ACTION_HEADER_0_SIZE)
2484             self.n_slaves = len(self.slaves)
2485             for s in self.slaves:
2486                 msg_pack_into('!H', data, slave_offset, s)
2487                 slave_offset += 2
2488             pad_len = (utils.round_up(self.n_slaves, 4) -
2489                        self.n_slaves)
2490
2491             if pad_len != 0:
2492                 msg_pack_into('%dx' % pad_len * 2, data, slave_offset)
2493
2494             msg_pack_into(self._fmt_str, data, 0,
2495                           self.algorithm, self.fields, self.basis,
2496                           self.slave_type, self.n_slaves,
2497                           self.ofs_nbits)
2498             offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
2499                       nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
2500
2501             if self.dst == 0:
2502                 msg_pack_into('I', data, offset, self.dst)
2503             else:
2504                 oxm_data = ofp.oxm_from_user_header(self.dst)
2505                 ofp.oxm_serialize_header(oxm_data, data, offset)
2506             return data
2507
2508     class NXActionBundle(_NXActionBundleBase):
2509         r"""
2510         Select bundle link action
2511
2512         This action selects bundle link based on the specified parameters.
2513         Please refer to the ovs-ofctl command manual for details.
2514
2515         And equivalent to the followings action of ovs-ofctl command.
2516
2517         ..
2518           bundle(fields, basis, algorithm, slave_type, slaves:[ s1, s2,...])
2519         ..
2520
2521         +-----------------------------------------------------------+
2522         | **bundle(**\ *fields*\, \ *basis*\, \ *algorithm*\,       |
2523         | *slave_type*\, \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** |
2524         +-----------------------------------------------------------+
2525
2526         ================ ======================================================
2527         Attribute        Description
2528         ================ ======================================================
2529         algorithm        One of NX_MP_ALG_*.
2530         fields           One of NX_HASH_FIELDS_*
2531         basis            Universal hash parameter
2532         slave_type       Type of slaves(must be NXM_OF_IN_PORT)
2533         n_slaves         Number of slaves
2534         ofs_nbits        Start and End for the OXM/NXM field. (must be zero)
2535         dst              OXM/NXM header for source field(must be zero)
2536         slaves           List of slaves
2537         ================ ======================================================
2538
2539
2540         Example::
2541
2542             actions += [parser.NXActionBundle(
2543                             algorithm=nicira_ext.NX_MP_ALG_HRW,
2544                             fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
2545                             basis=0,
2546                             slave_type=nicira_ext.NXM_OF_IN_PORT,
2547                             n_slaves=2,
2548                             ofs_nbits=0,
2549                             dst=0,
2550                             slaves=[2, 3])]
2551         """
2552         _subtype = nicira_ext.NXAST_BUNDLE
2553
2554         def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
2555                      ofs_nbits, dst, slaves):
2556             # NXAST_BUNDLE actions should have 'sofs_nbits' and 'dst' zeroed.
2557             super(NXActionBundle, self).__init__(
2558                 algorithm, fields, basis, slave_type, n_slaves,
2559                 ofs_nbits=0, dst=0, slaves=slaves)
2560
2561     class NXActionBundleLoad(_NXActionBundleBase):
2562         r"""
2563         Select bundle link action
2564
2565         This action has the same behavior as the bundle action,
2566         with one exception.
2567         Please refer to the ovs-ofctl command manual for details.
2568
2569         And equivalent to the followings action of ovs-ofctl command.
2570
2571         ..
2572           bundle_load(fields, basis, algorithm, slave_type,
2573                       dst[start..end], slaves:[ s1, s2,...])
2574         ..
2575
2576         +-----------------------------------------------------------+
2577         | **bundle_load(**\ *fields*\, \ *basis*\, \ *algorithm*\,  |
2578         | *slave_type*\, \ *dst*\[\ *start*\... \*emd*\],           |
2579         | \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** |              |
2580         +-----------------------------------------------------------+
2581
2582         ================ ======================================================
2583         Attribute        Description
2584         ================ ======================================================
2585         algorithm        One of NX_MP_ALG_*.
2586         fields           One of NX_HASH_FIELDS_*
2587         basis            Universal hash parameter
2588         slave_type       Type of slaves(must be NXM_OF_IN_PORT)
2589         n_slaves         Number of slaves
2590         ofs_nbits        Start and End for the OXM/NXM field.
2591                          Setting method refer to the ``nicira_ext.ofs_nbits``
2592         dst              OXM/NXM header for source field
2593         slaves           List of slaves
2594         ================ ======================================================
2595
2596
2597         Example::
2598
2599             actions += [parser.NXActionBundleLoad(
2600                             algorithm=nicira_ext.NX_MP_ALG_HRW,
2601                             fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
2602                             basis=0,
2603                             slave_type=nicira_ext.NXM_OF_IN_PORT,
2604                             n_slaves=2,
2605                             ofs_nbits=nicira_ext.ofs_nbits(4, 31),
2606                             dst="reg0",
2607                             slaves=[2, 3])]
2608         """
2609         _subtype = nicira_ext.NXAST_BUNDLE_LOAD
2610         _TYPE = {
2611             'ascii': [
2612                 'dst',
2613             ]
2614         }
2615
2616         def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
2617                      ofs_nbits, dst, slaves):
2618             super(NXActionBundleLoad, self).__init__(
2619                 algorithm, fields, basis, slave_type, n_slaves,
2620                 ofs_nbits, dst, slaves)
2621
2622     class NXActionCT(NXAction):
2623         r"""
2624         Pass traffic to the connection tracker action
2625
2626         This action sends the packet through the connection tracker.
2627
2628         And equivalent to the followings action of ovs-ofctl command.
2629
2630         ..
2631           ct(argument[,argument]...)
2632         ..
2633
2634         +------------------------------------------------+
2635         | **ct(**\ *argument*\[,\ *argument*\]...\ **)** |
2636         +------------------------------------------------+
2637
2638         ================ ======================================================
2639         Attribute        Description
2640         ================ ======================================================
2641         flags            Zero or more(Unspecified flag bits must be zero.)
2642         zone_src         OXM/NXM header for source field
2643         zone_ofs_nbits   Start and End for the OXM/NXM field.
2644                          Setting method refer to the ``nicira_ext.ofs_nbits``.
2645                          If you need set the Immediate value for zone,
2646                          zone_src must be set to None or empty character string.
2647         recirc_table     Recirculate to a specific table
2648         alg              Well-known port number for the protocol
2649         actions          Zero or more actions may immediately follow this
2650                          action
2651         ================ ======================================================
2652
2653         .. NOTE::
2654
2655             If you set number to zone_src,
2656             Traceback occurs when you run the to_jsondict.
2657
2658         Example::
2659
2660             match = parser.OFPMatch(eth_type=0x0800, ct_state=(0,32))
2661             actions += [parser.NXActionCT(
2662                             flags = 1,
2663                             zone_src = "reg0",
2664                             zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
2665                             recirc_table = 4,
2666                             alg = 0,
2667                             actions = [])]
2668         """
2669         _subtype = nicira_ext.NXAST_CT
2670
2671         # flags, zone_src, zone_ofs_nbits, recirc_table,
2672         # pad, alg
2673         _fmt_str = '!H4sHB3xH'
2674         _TYPE = {
2675             'ascii': [
2676                 'zone_src',
2677             ]
2678         }
2679
2680         # Followed by actions
2681
2682         def __init__(self,
2683                      flags,
2684                      zone_src,
2685                      zone_ofs_nbits,
2686                      recirc_table,
2687                      alg,
2688                      actions,
2689                      type_=None, len_=None, experimenter=None, subtype=None):
2690             super(NXActionCT, self).__init__()
2691             self.flags = flags
2692             self.zone_src = zone_src
2693             self.zone_ofs_nbits = zone_ofs_nbits
2694             self.recirc_table = recirc_table
2695             self.alg = alg
2696             self.actions = actions
2697
2698         @classmethod
2699         def parser(cls, buf):
2700             (flags,
2701              oxm_data,
2702              zone_ofs_nbits,
2703              recirc_table,
2704              alg,) = struct.unpack_from(
2705                 cls._fmt_str, buf, 0)
2706             rest = buf[struct.calcsize(cls._fmt_str):]
2707
2708             # OXM/NXM field
2709             if oxm_data == b'\x00' * 4:
2710                 zone_src = ""
2711             else:
2712                 (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
2713                 zone_src = ofp.oxm_to_user_header(n)
2714
2715             # actions
2716             actions = []
2717             while len(rest) > 0:
2718                 action = ofpp.OFPAction.parser(rest, 0)
2719                 actions.append(action)
2720                 rest = rest[action.len:]
2721
2722             return cls(flags, zone_src, zone_ofs_nbits, recirc_table,
2723                        alg, actions)
2724
2725         def serialize_body(self):
2726             data = bytearray()
2727             # If zone_src is zero, zone_ofs_nbits is zone_imm
2728             if not self.zone_src:
2729                 zone_src = b'\x00' * 4
2730             elif isinstance(self.zone_src, six.integer_types):
2731                 zone_src = struct.pack("!I", self.zone_src)
2732             else:
2733                 zone_src = bytearray()
2734                 oxm = ofp.oxm_from_user_header(self.zone_src)
2735                 ofp.oxm_serialize_header(oxm, zone_src, 0)
2736
2737             msg_pack_into(self._fmt_str, data, 0,
2738                           self.flags,
2739                           six.binary_type(zone_src),
2740                           self.zone_ofs_nbits,
2741                           self.recirc_table,
2742                           self.alg)
2743             for a in self.actions:
2744                 a.serialize(data, len(data))
2745             return data
2746
2747     class NXActionCTClear(NXAction):
2748         """
2749         Clear connection tracking state action
2750
2751         This action clears connection tracking state from packets.
2752
2753         And equivalent to the followings action of ovs-ofctl command.
2754
2755         ..
2756           ct_clear
2757         ..
2758
2759         +--------------+
2760         | **ct_clear** |
2761         +--------------+
2762
2763         Example::
2764
2765             actions += [parser.NXActionCTClear()]
2766         """
2767         _subtype = nicira_ext.NXAST_CT_CLEAR
2768
2769         _fmt_str = '!6x'
2770
2771         def __init__(self,
2772                      type_=None, len_=None, experimenter=None, subtype=None):
2773             super(NXActionCTClear, self).__init__()
2774
2775         @classmethod
2776         def parser(cls, buf):
2777             return cls()
2778
2779         def serialize_body(self):
2780             data = bytearray()
2781             msg_pack_into(self._fmt_str, data, 0)
2782             return data
2783
2784     class NXActionNAT(NXAction):
2785         r"""
2786         Network address translation action
2787
2788         This action sends the packet through the connection tracker.
2789
2790         And equivalent to the followings action of ovs-ofctl command.
2791
2792         .. NOTE::
2793             The following command image does not exist in ovs-ofctl command
2794             manual and has been created from the command response.
2795
2796         ..
2797           nat(src=ip_min-ip_max : proto_min-proto-max)
2798         ..
2799
2800         +--------------------------------------------------+
2801         | **nat(src**\=\ *ip_min*\ **-**\ *ip_max*\  **:** |
2802         | *proto_min*\ **-**\ *proto-max*\ **)**           |
2803         +--------------------------------------------------+
2804
2805         ================ ======================================================
2806         Attribute        Description
2807         ================ ======================================================
2808         flags            Zero or more(Unspecified flag bits must be zero.)
2809         range_ipv4_min   Range ipv4 address minimun
2810         range_ipv4_max   Range ipv4 address maximun
2811         range_ipv6_min   Range ipv6 address minimun
2812         range_ipv6_max   Range ipv6 address maximun
2813         range_proto_min  Range protocol minimum
2814         range_proto_max  Range protocol maximun
2815         ================ ======================================================
2816
2817         .. CAUTION::
2818             ``NXActionNAT`` must be defined in the actions in the
2819             ``NXActionCT``.
2820
2821         Example::
2822
2823             match = parser.OFPMatch(eth_type=0x0800)
2824             actions += [
2825                 parser.NXActionCT(
2826                     flags = 1,
2827                     zone_src = "reg0",
2828                     zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
2829                     recirc_table = 255,
2830                     alg = 0,
2831                     actions = [
2832                         parser.NXActionNAT(
2833                             flags = 1,
2834                             range_ipv4_min = "10.1.12.0",
2835                             range_ipv4_max = "10.1.13.255",
2836                             range_ipv6_min = "",
2837                             range_ipv6_max = "",
2838                             range_proto_min = 1,
2839                             range_proto_max = 1023
2840                         )
2841                     ]
2842                 )
2843             ]
2844         """
2845         _subtype = nicira_ext.NXAST_NAT
2846
2847         # pad, flags, range_present
2848         _fmt_str = '!2xHH'
2849         # Followed by optional parameters
2850
2851         _TYPE = {
2852             'ascii': [
2853                 'range_ipv4_max',
2854                 'range_ipv4_min',
2855                 'range_ipv6_max',
2856                 'range_ipv6_min',
2857             ]
2858         }
2859
2860         def __init__(self,
2861                      flags,
2862                      range_ipv4_min='',
2863                      range_ipv4_max='',
2864                      range_ipv6_min='',
2865                      range_ipv6_max='',
2866                      range_proto_min=None,
2867                      range_proto_max=None,
2868                      type_=None, len_=None, experimenter=None, subtype=None):
2869             super(NXActionNAT, self).__init__()
2870             self.flags = flags
2871             self.range_ipv4_min = range_ipv4_min
2872             self.range_ipv4_max = range_ipv4_max
2873             self.range_ipv6_min = range_ipv6_min
2874             self.range_ipv6_max = range_ipv6_max
2875             self.range_proto_min = range_proto_min
2876             self.range_proto_max = range_proto_max
2877
2878         @classmethod
2879         def parser(cls, buf):
2880             (flags,
2881              range_present) = struct.unpack_from(
2882                 cls._fmt_str, buf, 0)
2883             rest = buf[struct.calcsize(cls._fmt_str):]
2884             # optional parameters
2885             kwargs = dict()
2886             if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MIN:
2887                 kwargs['range_ipv4_min'] = type_desc.IPv4Addr.to_user(rest[:4])
2888                 rest = rest[4:]
2889             if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MAX:
2890                 kwargs['range_ipv4_max'] = type_desc.IPv4Addr.to_user(rest[:4])
2891                 rest = rest[4:]
2892             if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MIN:
2893                 kwargs['range_ipv6_min'] = (
2894                     type_desc.IPv6Addr.to_user(rest[:16]))
2895                 rest = rest[16:]
2896             if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MAX:
2897                 kwargs['range_ipv6_max'] = (
2898                     type_desc.IPv6Addr.to_user(rest[:16]))
2899                 rest = rest[16:]
2900             if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MIN:
2901                 kwargs['range_proto_min'] = type_desc.Int2.to_user(rest[:2])
2902                 rest = rest[2:]
2903             if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MAX:
2904                 kwargs['range_proto_max'] = type_desc.Int2.to_user(rest[:2])
2905
2906             return cls(flags, **kwargs)
2907
2908         def serialize_body(self):
2909             # Pack optional parameters first, as range_present needs
2910             # to be calculated.
2911             optional_data = b''
2912             range_present = 0
2913             if self.range_ipv4_min != '':
2914                 range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MIN
2915                 optional_data += type_desc.IPv4Addr.from_user(
2916                     self.range_ipv4_min)
2917             if self.range_ipv4_max != '':
2918                 range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MAX
2919                 optional_data += type_desc.IPv4Addr.from_user(
2920                     self.range_ipv4_max)
2921             if self.range_ipv6_min != '':
2922                 range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MIN
2923                 optional_data += type_desc.IPv6Addr.from_user(
2924                     self.range_ipv6_min)
2925             if self.range_ipv6_max != '':
2926                 range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MAX
2927                 optional_data += type_desc.IPv6Addr.from_user(
2928                     self.range_ipv6_max)
2929             if self.range_proto_min is not None:
2930                 range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MIN
2931                 optional_data += type_desc.Int2.from_user(
2932                     self.range_proto_min)
2933             if self.range_proto_max is not None:
2934                 range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MAX
2935                 optional_data += type_desc.Int2.from_user(
2936                     self.range_proto_max)
2937
2938             data = bytearray()
2939             msg_pack_into(self._fmt_str, data, 0,
2940                           self.flags,
2941                           range_present)
2942             msg_pack_into('!%ds' % len(optional_data), data, len(data),
2943                           optional_data)
2944
2945             return data
2946
2947     class NXActionOutputTrunc(NXAction):
2948         r"""
2949         Truncate output action
2950
2951         This action truncate a packet into the specified size and outputs it.
2952
2953         And equivalent to the followings action of ovs-ofctl command.
2954
2955         ..
2956           output(port=port,max_len=max_len)
2957         ..
2958
2959         +--------------------------------------------------------------+
2960         | **output(port**\=\ *port*\,\ **max_len**\=\ *max_len*\ **)** |
2961         +--------------------------------------------------------------+
2962
2963         ================ ======================================================
2964         Attribute        Description
2965         ================ ======================================================
2966         port             Output port
2967         max_len          Max bytes to send
2968         ================ ======================================================
2969
2970         Example::
2971
2972             actions += [parser.NXActionOutputTrunc(port=8080,
2973                                                    max_len=1024)]
2974         """
2975         _subtype = nicira_ext.NXAST_OUTPUT_TRUNC
2976
2977         # port, max_len
2978         _fmt_str = '!HI'
2979
2980         def __init__(self,
2981                      port,
2982                      max_len,
2983                      type_=None, len_=None, experimenter=None, subtype=None):
2984             super(NXActionOutputTrunc, self).__init__()
2985             self.port = port
2986             self.max_len = max_len
2987
2988         @classmethod
2989         def parser(cls, buf):
2990             (port,
2991              max_len) = struct.unpack_from(
2992                 cls._fmt_str, buf, 0)
2993             return cls(port, max_len)
2994
2995         def serialize_body(self):
2996             data = bytearray()
2997             msg_pack_into(self._fmt_str, data, 0,
2998                           self.port,
2999                           self.max_len)
3000             return data
3001
3002     class NXActionDecNshTtl(NXAction):
3003         """
3004         Decrement NSH TTL action
3005
3006         This action decrements the TTL in the Network Service Header(NSH).
3007
3008         This action was added in OVS v2.9.
3009
3010         And equivalent to the followings action of ovs-ofctl command.
3011
3012         ::
3013
3014             dec_nsh_ttl
3015
3016         Example::
3017
3018             actions += [parser.NXActionDecNshTtl()]
3019         """
3020         _subtype = nicira_ext.NXAST_DEC_NSH_TTL
3021
3022         _fmt_str = '!6x'
3023
3024         def __init__(self,
3025                      type_=None, len_=None, vendor=None, subtype=None):
3026             super(NXActionDecNshTtl, self).__init__()
3027
3028         @classmethod
3029         def parser(cls, buf):
3030             return cls()
3031
3032         def serialize_body(self):
3033             data = bytearray()
3034             msg_pack_into(self._fmt_str, data, 0)
3035             return data
3036
3037     def add_attr(k, v):
3038         v.__module__ = ofpp.__name__  # Necessary for stringify stuff
3039         setattr(ofpp, k, v)
3040
3041     add_attr('NXAction', NXAction)
3042     add_attr('NXActionUnknown', NXActionUnknown)
3043
3044     classes = [
3045         'NXActionSetQueue',
3046         'NXActionPopQueue',
3047         'NXActionRegLoad',
3048         'NXActionRegLoad2',
3049         'NXActionNote',
3050         'NXActionSetTunnel',
3051         'NXActionSetTunnel64',
3052         'NXActionRegMove',
3053         'NXActionResubmit',
3054         'NXActionResubmitTable',
3055         'NXActionOutputReg',
3056         'NXActionOutputReg2',
3057         'NXActionLearn',
3058         'NXActionExit',
3059         'NXActionDecTtl',
3060         'NXActionController',
3061         'NXActionController2',
3062         'NXActionDecTtlCntIds',
3063         'NXActionPushMpls',
3064         'NXActionPopMpls',
3065         'NXActionSetMplsTtl',
3066         'NXActionDecMplsTtl',
3067         'NXActionSetMplsLabel',
3068         'NXActionSetMplsTc',
3069         'NXActionStackPush',
3070         'NXActionStackPop',
3071         'NXActionSample',
3072         'NXActionSample2',
3073         'NXActionFinTimeout',
3074         'NXActionConjunction',
3075         'NXActionMultipath',
3076         'NXActionBundle',
3077         'NXActionBundleLoad',
3078         'NXActionCT',
3079         'NXActionCTClear',
3080         'NXActionNAT',
3081         'NXActionOutputTrunc',
3082         '_NXFlowSpec',  # exported for testing
3083         'NXFlowSpecMatch',
3084         'NXFlowSpecLoad',
3085         'NXFlowSpecOutput',
3086         'NXActionDecNshTtl',
3087     ]
3088     vars = locals()
3089     for name in classes:
3090         cls = vars[name]
3091         add_attr(name, cls)
3092         if issubclass(cls, NXAction):
3093             NXAction.register(cls)
3094         if issubclass(cls, _NXFlowSpec):
3095             _NXFlowSpec.register(cls)