1 # Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
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
29 def generate(ofp_name, ofpp_name):
32 ofp = sys.modules[ofp_name]
33 ofpp = sys.modules[ofpp_name]
35 class _NXFlowSpec(StringifyMixin):
36 _hdr_fmt_str = '!H' # 2 bit 0s, 1 bit src, 2 bit dst, 11 bit n_bits
40 'nx-flow-spec-field': [
46 def __init__(self, src, dst, n_bits):
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
59 (hdr,) = struct.unpack_from(cls._hdr_fmt_str, buf, 0)
60 rest = buf[struct.calcsize(cls._hdr_fmt_str):]
62 return None, rest # all-0 header is no-op for padding
63 src_type = (hdr >> 13) & 0x1
64 dst_type = (hdr >> 11) & 0x3
66 subcls = cls._subclasses[dst_type]
67 if src_type == 0: # subfield
68 src = cls._parse_subfield(rest)
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)
75 if dst_type == 0: # match
76 dst = cls._parse_subfield(rest)
78 elif dst_type == 1: # load
79 dst = cls._parse_subfield(rest)
81 elif dst_type == 2: # output
83 return subcls(src=src, dst=dst, n_bits=n_bits), rest
87 if isinstance(self.src, tuple):
88 src_type = 0 # subfield
90 src_type = 1 # immediate
92 val = (src_type << 13) | (self._dst_type << 11) | self.n_bits
93 msg_pack_into(self._hdr_fmt_str, buf, 0, val)
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)
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
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)
115 (ofs,) = struct.unpack_from('!H', rest, 0)
119 def _serialize_subfield(subfield):
120 (field, ofs) = subfield
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)
128 class NXFlowSpecMatch(_NXFlowSpec):
130 Specification for adding match criterion
132 This class is used by ``NXActionLearn``.
134 For the usage of this class, please refer to ``NXActionLearn``.
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 ================ ======================================================
144 # Add a match criteria
145 # an example of the corresponding ovs-ofctl syntax:
146 # NXM_OF_VLAN_TCI[0..11]
149 class NXFlowSpecLoad(_NXFlowSpec):
151 Add NXAST_REG_LOAD actions
153 This class is used by ``NXActionLearn``.
155 For the usage of this class, please refer to ``NXActionLearn``.
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 ================ ======================================================
165 # Add NXAST_REG_LOAD actions
166 # an example of the corresponding ovs-ofctl syntax:
167 # NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
170 class NXFlowSpecOutput(_NXFlowSpec):
172 Add an OFPAT_OUTPUT action
174 This class is used by ``NXActionLearn``.
176 For the usage of this class, please refer to ``NXActionLearn``.
178 ================ ======================================================
179 Attribute Description
180 ================ ======================================================
181 src OXM/NXM header and Start bit for source field
183 n_bits The number of bits from the start bit
184 ================ ======================================================
186 # Add an OFPAT_OUTPUT action
187 # an example of the corresponding ovs-ofctl syntax:
188 # output:NXM_OF_IN_PORT[]
191 def __init__(self, src, n_bits, dst=''):
193 super(NXFlowSpecOutput, self).__init__(src=src, dst=dst,
196 class NXAction(ofpp.OFPActionExperimenter):
197 _fmt_str = '!H' # subtype
199 _experimenter = ofproto_common.NX_EXPERIMENTER_ID
202 super(NXAction, self).__init__(self._experimenter)
203 self.subtype = self._subtype
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)
215 def serialize(self, buf, offset):
216 data = self.serialize_body()
218 ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE +
219 struct.calcsize(NXAction._fmt_str)
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,
225 offset + ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE,
230 def register(cls, subtype_cls):
231 assert subtype_cls._subtype is not cls._subtypes
232 cls._subtypes[subtype_cls._subtype] = subtype_cls
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__()
242 def parser(cls, buf):
245 def serialize_body(self):
247 return bytearray() if self.data is None else self.data
249 # For OpenFlow1.0 only
250 class NXActionSetQueue(NXAction):
254 This action sets the queue that should be used to queue
255 when packets are output.
257 And equivalent to the followings action of ovs-ofctl command.
263 +-------------------------+
264 | **set_queue**\:\ *queue*|
265 +-------------------------+
267 ================ ======================================================
268 Attribute Description
269 ================ ======================================================
270 queue_id Queue ID for the packets
271 ================ ======================================================
274 This actions is supported by
275 ``OFPActionSetQueue``
276 in OpenFlow1.2 or later.
280 actions += [parser.NXActionSetQueue(queue_id=10)]
282 _subtype = nicira_ext.NXAST_SET_QUEUE
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
293 def parser(cls, buf):
294 (queue_id,) = struct.unpack_from(cls._fmt_str, buf, 0)
297 def serialize_body(self):
299 msg_pack_into(self._fmt_str, data, 0, self.queue_id)
302 class NXActionPopQueue(NXAction):
306 This action restors the queue to the value it was before any
307 set_queue actions were applied.
309 And equivalent to the followings action of ovs-ofctl command.
321 actions += [parser.NXActionPopQueue()]
323 _subtype = nicira_ext.NXAST_POP_QUEUE
328 type_=None, len_=None, experimenter=None, subtype=None):
329 super(NXActionPopQueue, self).__init__()
332 def parser(cls, buf):
335 def serialize_body(self):
337 msg_pack_into(self._fmt_str, data, 0)
340 class NXActionRegLoad(NXAction):
342 Load literal value action
344 This action loads a literal value into a field or part of a field.
346 And equivalent to the followings action of ovs-ofctl command.
349 load:value->dst[start..end]
352 +-----------------------------------------------------------------+
353 | **load**\:\ *value*\->\ *dst*\ **[**\ *start*\..\ *end*\ **]** |
354 +-----------------------------------------------------------------+
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 ================ ======================================================
367 actions += [parser.NXActionRegLoad(
368 ofs_nbits=nicira_ext.ofs_nbits(4, 31),
372 _subtype = nicira_ext.NXAST_REG_LOAD
373 _fmt_str = '!HIQ' # ofs_nbits, dst, value
380 def __init__(self, ofs_nbits, dst, value,
381 type_=None, len_=None, experimenter=None,
383 super(NXActionRegLoad, self).__init__()
384 self.ofs_nbits = ofs_nbits
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)
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)
403 msg_pack_into(self._fmt_str, data, 0,
404 self.ofs_nbits, dst_num, self.value)
407 class NXActionRegLoad2(NXAction):
409 Load literal value action
411 This action loads a literal value into a field or part of a field.
413 And equivalent to the followings action of ovs-ofctl command.
416 set_field:value[/mask]->dst
419 +------------------------------------------------------------+
420 | **set_field**\:\ *value*\ **[**\/\ *mask*\ **]**\->\ *dst* |
421 +------------------------------------------------------------+
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 ================ ======================================================
433 actions += [parser.NXActionRegLoad2(dst="tun_ipv4_src",
434 value="192.168.10.0",
435 mask="255.255.255.0")]
437 _subtype = nicira_ext.NXAST_REG_LOAD2
445 def __init__(self, dst, value, mask=None,
446 type_=None, len_=None, experimenter=None, subtype=None):
447 super(NXActionRegLoad2, self).__init__()
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)
457 if isinstance(value, (tuple, list)):
458 return cls(dst, value[0], value[1])
460 return cls(dst, value, None)
462 def serialize_body(self):
464 if self.mask is None:
467 value = (self.value, self.mask)
468 self._TYPE['ascii'].append('mask')
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_)
476 class NXActionNote(NXAction):
480 This action does nothing at all.
482 And equivalent to the followings action of ovs-ofctl command.
488 +-----------------------------------+
489 | **note**\:\ **[**\ *hh*\ **]**\.. |
490 +-----------------------------------+
492 ================ ======================================================
493 Attribute Description
494 ================ ======================================================
495 note A list of integer type values
496 ================ ======================================================
500 actions += [parser.NXActionNote(note=[0xaa,0xbb,0xcc,0xdd])]
502 _subtype = nicira_ext.NXAST_NOTE
507 # set the integer array in a note
510 type_=None, len_=None, experimenter=None, subtype=None):
511 super(NXActionNote, self).__init__()
515 def parser(cls, buf):
516 note = struct.unpack_from(
517 cls._fmt_str % len(buf), buf, 0)
518 return cls(list(note))
520 def serialize_body(self):
521 assert isinstance(self.note, (tuple, list))
523 assert isinstance(n, six.integer_types)
525 pad = (len(self.note) + nicira_ext.NX_ACTION_HEADER_0_SIZE) % 8
527 self.note += [0x0 for i in range(8 - pad)]
528 note_len = len(self.note)
530 msg_pack_into(self._fmt_str % note_len, data, 0,
534 class _NXActionSetTunnelBase(NXAction):
535 # _subtype, _fmt_str must be attributes of subclass.
539 type_=None, len_=None, experimenter=None, subtype=None):
540 super(_NXActionSetTunnelBase, self).__init__()
544 def parser(cls, buf):
545 (tun_id,) = struct.unpack_from(
546 cls._fmt_str, buf, 0)
549 def serialize_body(self):
551 msg_pack_into(self._fmt_str, data, 0,
555 class NXActionSetTunnel(_NXActionSetTunnelBase):
559 This action sets the identifier (such as GRE) to the specified id.
561 And equivalent to the followings action of ovs-ofctl command.
564 This actions is supported by
565 ``OFPActionSetField``
566 in OpenFlow1.2 or later.
572 +------------------------+
573 | **set_tunnel**\:\ *id* |
574 +------------------------+
576 ================ ======================================================
577 Attribute Description
578 ================ ======================================================
579 tun_id Tunnel ID(32bits)
580 ================ ======================================================
584 actions += [parser.NXActionSetTunnel(tun_id=0xa)]
586 _subtype = nicira_ext.NXAST_SET_TUNNEL
591 class NXActionSetTunnel64(_NXActionSetTunnelBase):
595 This action outputs to a port that encapsulates
596 the packet in a tunnel.
598 And equivalent to the followings action of ovs-ofctl command.
601 This actions is supported by
602 ``OFPActionSetField``
603 in OpenFlow1.2 or later.
609 +--------------------------+
610 | **set_tunnel64**\:\ *id* |
611 +--------------------------+
613 ================ ======================================================
614 Attribute Description
615 ================ ======================================================
616 tun_id Tunnel ID(64bits)
617 ================ ======================================================
621 actions += [parser.NXActionSetTunnel64(tun_id=0xa)]
623 _subtype = nicira_ext.NXAST_SET_TUNNEL64
628 class NXActionRegMove(NXAction):
632 This action copies the src to dst.
634 And equivalent to the followings action of ovs-ofctl command.
637 move:src[start..end]->dst[start..end]
640 +--------------------------------------------------------+
641 | **move**\:\ *src*\ **[**\ *start*\..\ *end*\ **]**\->\ |
642 | *dst*\ **[**\ *start*\..\ *end* \ **]** |
643 +--------------------------------------------------------+
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 ================ ======================================================
656 **src_start**\ and \ **src_end**\ difference and \ **dst_start**\
657 and \ **dst_end**\ difference must be the same.
661 actions += [parser.NXActionRegMove(src_field="reg0",
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
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__()
681 self.src_ofs = src_ofs
682 self.dst_ofs = dst_ofs
683 self.src_field = src_field
684 self.dst_field = dst_field
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):]
693 (n, len) = ofp.oxm_parse_header(rest, 0)
694 src_field = ofp.oxm_to_user_header(n)
697 (n, len) = ofp.oxm_parse_header(rest, 0)
698 dst_field = ofp.oxm_to_user_header(n)
701 return cls(src_field, dst_field=dst_field, n_bits=n_bits,
702 src_ofs=src_ofs, dst_ofs=dst_ofs)
704 def serialize_body(self):
707 msg_pack_into(self._fmt_str, data, 0,
708 self.n_bits, self.src_ofs, self.dst_ofs)
710 n = ofp.oxm_from_user_header(self.src_field)
711 ofp.oxm_serialize_header(n, data, len(data))
713 n = ofp.oxm_from_user_header(self.dst_field)
714 ofp.oxm_serialize_header(n, data, len(data))
717 class NXActionResubmit(NXAction):
721 This action searches one of the switch's flow tables.
723 And equivalent to the followings action of ovs-ofctl command.
729 +------------------------+
730 | **resubmit**\:\ *port* |
731 +------------------------+
733 ================ ======================================================
734 Attribute Description
735 ================ ======================================================
736 in_port New in_port for checking flow table
737 ================ ======================================================
741 actions += [parser.NXActionResubmit(in_port=8080)]
743 _subtype = nicira_ext.NXAST_RESUBMIT
750 type_=None, len_=None, experimenter=None, subtype=None):
751 super(NXActionResubmit, self).__init__()
752 self.in_port = in_port
755 def parser(cls, buf):
756 (in_port,) = struct.unpack_from(
757 cls._fmt_str, buf, 0)
760 def serialize_body(self):
762 msg_pack_into(self._fmt_str, data, 0,
766 class NXActionResubmitTable(NXAction):
770 This action searches one of the switch's flow tables.
772 And equivalent to the followings action of ovs-ofctl command.
775 resubmit([port],[table])
778 +------------------------------------------------+
779 | **resubmit(**\[\ *port*\]\,[\ *table*\]\ **)** |
780 +------------------------------------------------+
782 ================ ======================================================
783 Attribute Description
784 ================ ======================================================
785 in_port New in_port for checking flow table
786 table_id Checking flow tables
787 ================ ======================================================
791 actions += [parser.NXActionResubmit(in_port=8080,
794 _subtype = nicira_ext.NXAST_RESUBMIT_TABLE
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
808 def parser(cls, buf):
810 table_id) = struct.unpack_from(
811 cls._fmt_str, buf, 0)
812 return cls(in_port, table_id)
814 def serialize_body(self):
816 msg_pack_into(self._fmt_str, data, 0,
817 self.in_port, self.table_id)
820 class NXActionOutputReg(NXAction):
824 This action outputs the packet to the OpenFlow port number read from
827 And equivalent to the followings action of ovs-ofctl command.
830 output:src[start...end]
833 +-------------------------------------------------------+
834 | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
835 +-------------------------------------------------------+
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 ================ ======================================================
848 actions += [parser.NXActionOutputReg(
849 ofs_nbits=nicira_ext.ofs_nbits(4, 31),
853 _subtype = nicira_ext.NXAST_OUTPUT_REG
855 # ofs_nbits, src, max_len
867 type_=None, len_=None, experimenter=None, subtype=None):
868 super(NXActionOutputReg, self).__init__()
869 self.ofs_nbits = ofs_nbits
871 self.max_len = max_len
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,
883 def serialize_body(self):
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,
890 six.binary_type(src),
894 class NXActionOutputReg2(NXAction):
898 This action outputs the packet to the OpenFlow port number read from
901 And equivalent to the followings action of ovs-ofctl command.
904 output:src[start...end]
907 +-------------------------------------------------------+
908 | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
909 +-------------------------------------------------------+
912 Like the ``NXActionOutputReg`` but organized so
913 that there is room for a 64-bit experimenter OXM as 'src'.
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 ================ ======================================================
926 actions += [parser.NXActionOutputReg2(
927 ofs_nbits=nicira_ext.ofs_nbits(4, 31),
931 _subtype = nicira_ext.NXAST_OUTPUT_REG2
933 # ofs_nbits, src, max_len
945 type_=None, len_=None, experimenter=None, subtype=None):
946 super(NXActionOutputReg2, self).__init__()
947 self.ofs_nbits = ofs_nbits
949 self.max_len = max_len
952 def parser(cls, buf):
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,
963 def serialize_body(self):
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,
971 six.binary_type(oxm_data))
973 msg_pack_into("!%dx" % (14 - offset), data, offset)
976 class NXActionLearn(NXAction):
978 Adds or modifies flow action
980 This action adds or modifies a flow in OpenFlow table.
982 And equivalent to the followings action of ovs-ofctl command.
985 learn(argument[,argument]...)
988 +---------------------------------------------------+
989 | **learn(**\ *argument*\[,\ *argument*\]...\ **)** |
990 +---------------------------------------------------+
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
1000 in order to set the following format
1004 field[start..end]=src[start..end]
1008 | *field*\=\ *value*
1009 | *field*\ **[**\ *start*\..\ *end*\ **]**\ =\
1010 *src*\ **[**\ *start*\..\ *end*\ **]**
1011 | *field*\ **[**\ *start*\..\ *end*\ **]**
1016 in order to set the following format
1019 load:value->dst[start..end]
1020 load:src[start..end]->dst[start..end]
1023 | **load**\:\ *value*\ **->**\ *dst*\
1024 **[**\ *start*\..\ *end*\ **]**
1025 | **load**\:\ *src*\ **[**\ *start*\..\ *end*\
1026 **] ->**\ *dst*\ **[**\ *start*\..\ *end*\ **]**
1030 ``NXFlowSpecOutput``
1031 in order to set the following format
1034 output:field[start..end]
1037 | **output:**\ field\ **[**\ *start*\..\ *end*\ **]**
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
1044 fin_idle_timeout Idle timeout after FIN(seconds)
1045 fin_hard_timeout Hard timeout after FIN(seconds)
1046 ================ ======================================================
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.
1057 parser.NXActionLearn(able_id=10,
1058 specs=[parser.NXFlowSpecMatch(src=0x800,
1059 dst=('eth_type_nxm', 0),
1061 parser.NXFlowSpecMatch(src=('reg1', 1),
1064 parser.NXFlowSpecMatch(src=('reg3', 1),
1067 parser.NXFlowSpecLoad(src=0,
1070 parser.NXFlowSpecLoad(src=('reg5', 1),
1073 parser.NXFlowSpecOutput(src=('reg7', 1),
1080 flags=ofproto.OFPFF_SEND_FLOW_REM,
1081 fin_idle_timeout=180,
1082 fin_hard_timeout=300)]
1084 _subtype = nicira_ext.NXAST_LEARN
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
1096 priority=ofp.OFP_DEFAULT_PRIORITY,
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
1108 self.table_id = table_id
1109 self.fin_idle_timeout = fin_idle_timeout
1110 self.fin_hard_timeout = fin_hard_timeout
1114 def parser(cls, buf):
1122 fin_hard_timeout,) = struct.unpack_from(
1123 cls._fmt_str, buf, 0)
1124 rest = buf[struct.calcsize(cls._fmt_str):]
1127 while len(rest) > 0:
1128 spec, rest = _NXFlowSpec.parse(rest)
1132 return cls(idle_timeout=idle_timeout,
1133 hard_timeout=hard_timeout,
1138 fin_idle_timeout=fin_idle_timeout,
1139 fin_hard_timeout=fin_hard_timeout,
1142 def serialize_body(self):
1145 msg_pack_into(self._fmt_str, data, 0,
1152 self.fin_idle_timeout,
1153 self.fin_hard_timeout)
1154 for spec in self.specs:
1155 data += spec.serialize()
1158 class NXActionExit(NXAction):
1162 This action causes OpenvSwitch to immediately halt
1163 execution of further actions.
1165 And equivalent to the followings action of ovs-ofctl command.
1177 actions += [parser.NXActionExit()]
1179 _subtype = nicira_ext.NXAST_EXIT
1184 type_=None, len_=None, experimenter=None, subtype=None):
1185 super(NXActionExit, self).__init__()
1188 def parser(cls, buf):
1191 def serialize_body(self):
1193 msg_pack_into(self._fmt_str, data, 0)
1196 # For OpenFlow1.0 only
1197 class NXActionDecTtl(NXAction):
1199 Decrement IP TTL action
1201 This action decrements TTL of IPv4 packet or
1202 hop limit of IPv6 packet.
1204 And equivalent to the followings action of ovs-ofctl command.
1215 This actions is supported by
1216 ``OFPActionDecNwTtl``
1217 in OpenFlow1.2 or later.
1221 actions += [parser.NXActionDecTtl()]
1223 _subtype = nicira_ext.NXAST_DEC_TTL
1228 type_=None, len_=None, vendor=None, subtype=None):
1229 super(NXActionDecTtl, self).__init__()
1232 def parser(cls, buf):
1235 def serialize_body(self):
1237 msg_pack_into(self._fmt_str, data, 0)
1240 class NXActionController(NXAction):
1242 Send packet in message action
1244 This action sends the packet to the OpenFlow controller as
1245 a packet in message.
1247 And equivalent to the followings action of ovs-ofctl command.
1250 controller(key=value...)
1253 +----------------------------------------------+
1254 | **controller(**\ *key*\=\ *value*\...\ **)** |
1255 +----------------------------------------------+
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 ================ ======================================================
1268 parser.NXActionController(max_len=1024,
1270 reason=ofproto.OFPR_INVALID_TTL)]
1272 _subtype = nicira_ext.NXAST_CONTROLLER
1274 # max_len, controller_id, 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
1288 def parser(cls, buf):
1291 reason) = struct.unpack_from(
1297 def serialize_body(self):
1299 msg_pack_into(self._fmt_str, data, 0,
1305 class NXActionController2(NXAction):
1307 Send packet in message action
1309 This action sends the packet to the OpenFlow controller as
1310 a packet in message.
1312 And equivalent to the followings action of ovs-ofctl command.
1315 controller(key=value...)
1318 +----------------------------------------------+
1319 | **controller(**\ *key*\=\ *value*\...\ **)** |
1320 +----------------------------------------------+
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
1330 pause Flag to pause pipeline to resume later
1331 ================ ======================================================
1336 parser.NXActionController(max_len=1024,
1338 reason=ofproto.OFPR_INVALID_TTL,
1339 userdata=[0xa,0xb,0xc],
1342 _subtype = nicira_ext.NXAST_CONTROLLER2
1347 type_=None, len_=None, vendor=None, subtype=None,
1349 super(NXActionController2, self).__init__()
1352 if arg in NXActionController2Prop._NAMES:
1353 setattr(self, arg, kwargs[arg])
1356 def parser(cls, buf):
1360 while buf_len > offset:
1361 (type_, length) = struct.unpack_from(cls._PACK_STR, buf, offset)
1364 subcls = NXActionController2Prop._TYPES[type_]
1366 subcls = NXActionController2PropUnknown
1367 data, size = subcls.parser_prop(buf[offset:], length - 4)
1369 cls_data[subcls._arg_name] = data
1370 return cls(**cls_data)
1372 def serialize_body(self):
1374 msg_pack_into(self._fmt_str, body, 0)
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)
1382 for subcls, value in prop_list:
1383 body += subcls.serialize_prop(value)
1387 class NXActionController2Prop(object):
1392 def register_type(cls, type_):
1393 def _register_type(subcls):
1395 NXActionController2Prop._TYPES[type_] = subcls
1396 NXActionController2Prop._NAMES[subcls._arg_name] = subcls
1399 return _register_type
1401 class NXActionController2PropUnknown(NXActionController2Prop):
1404 def parser_prop(cls, buf, length):
1409 def serialize_prop(cls, argment):
1413 @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_MAX_LEN)
1414 class NXActionController2PropMaxLen(NXActionController2Prop):
1417 _arg_name = "max_len"
1420 def parser_prop(cls, buf, length):
1422 (max_len,) = struct.unpack_from(
1423 cls._fmt_str, buf, 0)
1424 return max_len, size
1427 def serialize_prop(cls, max_len):
1429 msg_pack_into("!HHH2x", data, 0,
1430 nicira_ext.NXAC2PT_MAX_LEN,
1435 @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_CONTROLLER_ID)
1436 class NXActionController2PropControllerId(NXActionController2Prop):
1439 _arg_name = "controller_id"
1442 def parser_prop(cls, buf, length):
1444 (controller_id,) = struct.unpack_from(
1445 cls._fmt_str, buf, 0)
1446 return controller_id, size
1449 def serialize_prop(cls, controller_id):
1451 msg_pack_into("!HHH2x", data, 0,
1452 nicira_ext.NXAC2PT_CONTROLLER_ID,
1457 @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_REASON)
1458 class NXActionController2PropReason(NXActionController2Prop):
1461 _arg_name = "reason"
1464 def parser_prop(cls, buf, length):
1466 (reason,) = struct.unpack_from(
1467 cls._fmt_str, buf, 0)
1471 def serialize_prop(cls, reason):
1473 msg_pack_into("!HHB3x", data, 0,
1474 nicira_ext.NXAC2PT_REASON,
1479 @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_USERDATA)
1480 class NXActionController2PropUserData(NXActionController2Prop):
1483 _arg_name = "userdata"
1486 def parser_prop(cls, buf, length):
1490 while offset < length:
1491 u = struct.unpack_from(cls._fmt_str, buf, offset)
1492 userdata.append(u[0])
1495 user_size = utils.round_up(length, 4)
1497 if user_size > 4 and (user_size % 8) == 0:
1498 size = utils.round_up(length, 4) + 4
1500 size = utils.round_up(length, 4)
1502 return userdata, size
1505 def serialize_prop(cls, userdata):
1507 user_buf = bytearray()
1509 for user in userdata:
1510 msg_pack_into('!B', user_buf, user_offset,
1514 msg_pack_into("!HH", data, 0,
1515 nicira_ext.NXAC2PT_USERDATA,
1520 user_len = utils.round_up(user_offset, 4)
1522 if (user_len % 8) == 0:
1524 msg_pack_into("!%dx" % (user_len - user_offset + brank_size),
1525 data, 4 + user_offset)
1527 user_len = utils.round_up(user_offset, 4)
1529 msg_pack_into("!%dx" % (user_len - user_offset),
1530 data, 4 + user_offset)
1533 @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_PAUSE)
1534 class NXActionController2PropPause(NXActionController2Prop):
1538 def parser_prop(cls, buf, length):
1544 def serialize_prop(cls, pause):
1546 msg_pack_into("!HH4x", data, 0,
1547 nicira_ext.NXAC2PT_PAUSE,
1551 class NXActionDecTtlCntIds(NXAction):
1553 Decrement TTL action
1555 This action decrements TTL of IPv4 packet or
1556 hop limits of IPv6 packet.
1558 And equivalent to the followings action of ovs-ofctl command.
1561 dec_ttl(id1[,id2]...)
1564 +-------------------------------------------+
1565 | **dec_ttl(**\ *id1*\[,\ *id2*\]...\ **)** |
1566 +-------------------------------------------+
1568 ================ ======================================================
1569 Attribute Description
1570 ================ ======================================================
1571 cnt_ids Controller ids
1572 ================ ======================================================
1576 actions += [parser.NXActionDecTtlCntIds(cnt_ids=[1,2,3])]
1579 If you want to set the following ovs-ofctl command.
1580 Please use ``OFPActionDecNwTtl``.
1586 _subtype = nicira_ext.NXAST_DEC_TTL_CNT_IDS
1594 type_=None, len_=None, experimenter=None, subtype=None):
1595 super(NXActionDecTtlCntIds, self).__init__()
1597 self.cnt_ids = cnt_ids
1600 def parser(cls, buf):
1601 (controllers,) = struct.unpack_from(
1604 offset = cls._fmt_len
1607 for i in range(0, controllers):
1608 id_ = struct.unpack_from('!H', buf, offset)
1609 cnt_ids.append(id_[0])
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)
1619 controllers = len(self.cnt_ids)
1622 msg_pack_into(self._fmt_str, data, 0,
1624 offset = self._fmt_len
1626 for id_ in self.cnt_ids:
1627 msg_pack_into('!H', data, offset, id_)
1630 id_len = (utils.round_up(controllers, 4) -
1634 msg_pack_into('%dx' % id_len * 2, data, offset)
1638 # Use in only OpenFlow1.0
1639 class NXActionMplsBase(NXAction):
1645 type_=None, len_=None, vendor=None, subtype=None):
1646 super(NXActionMplsBase, self).__init__()
1647 self.ethertype = ethertype
1650 def parser(cls, buf):
1651 (ethertype,) = struct.unpack_from(
1653 return cls(ethertype)
1655 def serialize_body(self):
1657 msg_pack_into(self._fmt_str, data, 0,
1661 # For OpenFlow1.0 only
1662 class NXActionPushMpls(NXActionMplsBase):
1666 This action pushes a new MPLS header to the packet.
1668 And equivalent to the followings action of ovs-ofctl command.
1674 +-------------------------------+
1675 | **push_mpls**\:\ *ethertype* |
1676 +-------------------------------+
1678 ================ ======================================================
1679 Attribute Description
1680 ================ ======================================================
1681 ethertype Ether type(The value must be either 0x8847 or 0x8848)
1682 ================ ======================================================
1685 This actions is supported by
1686 ``OFPActionPushMpls``
1687 in OpenFlow1.2 or later.
1691 match = parser.OFPMatch(dl_type=0x0800)
1692 actions += [parser.NXActionPushMpls(ethertype=0x8847)]
1694 _subtype = nicira_ext.NXAST_PUSH_MPLS
1696 # For OpenFlow1.0 only
1697 class NXActionPopMpls(NXActionMplsBase):
1701 This action pops the MPLS header from the packet.
1703 And equivalent to the followings action of ovs-ofctl command.
1709 +------------------------------+
1710 | **pop_mpls**\:\ *ethertype* |
1711 +------------------------------+
1713 ================ ======================================================
1714 Attribute Description
1715 ================ ======================================================
1716 ethertype Ether type
1717 ================ ======================================================
1720 This actions is supported by
1721 ``OFPActionPopMpls``
1722 in OpenFlow1.2 or later.
1726 match = parser.OFPMatch(dl_type=0x8847)
1727 actions += [parser.NXActionPushMpls(ethertype=0x0800)]
1729 _subtype = nicira_ext.NXAST_POP_MPLS
1731 # For OpenFlow1.0 only
1732 class NXActionSetMplsTtl(NXAction):
1736 This action sets the MPLS TTL.
1738 And equivalent to the followings action of ovs-ofctl command.
1744 +---------------------------+
1745 | **set_mpls_ttl**\:\ *ttl* |
1746 +---------------------------+
1748 ================ ======================================================
1749 Attribute Description
1750 ================ ======================================================
1752 ================ ======================================================
1755 This actions is supported by
1756 ``OFPActionSetMplsTtl``
1757 in OpenFlow1.2 or later.
1761 actions += [parser.NXActionSetMplsTil(ttl=128)]
1763 _subtype = nicira_ext.NXAST_SET_MPLS_TTL
1770 type_=None, len_=None, vendor=None, subtype=None):
1771 super(NXActionSetMplsTtl, self).__init__()
1775 def parser(cls, buf):
1776 (ttl,) = struct.unpack_from(
1780 def serialize_body(self):
1782 msg_pack_into(self._fmt_str, data, 0,
1786 # For OpenFlow1.0 only
1787 class NXActionDecMplsTtl(NXAction):
1789 Decrement MPLS TTL action
1791 This action decrements the MPLS TTL.
1793 And equivalent to the followings action of ovs-ofctl command.
1799 +------------------+
1800 | **dec_mpls_ttl** |
1801 +------------------+
1804 This actions is supported by
1805 ``OFPActionDecMplsTtl``
1806 in OpenFlow1.2 or later.
1810 actions += [parser.NXActionDecMplsTil()]
1812 _subtype = nicira_ext.NXAST_DEC_MPLS_TTL
1818 type_=None, len_=None, vendor=None, subtype=None):
1819 super(NXActionDecMplsTtl, self).__init__()
1822 def parser(cls, buf):
1825 def serialize_body(self):
1827 msg_pack_into(self._fmt_str, data, 0)
1830 # For OpenFlow1.0 only
1831 class NXActionSetMplsLabel(NXAction):
1833 Set MPLS Lavel action
1835 This action sets the MPLS Label.
1837 And equivalent to the followings action of ovs-ofctl command.
1840 set_mpls_label:label
1843 +-------------------------------+
1844 | **set_mpls_label**\:\ *label* |
1845 +-------------------------------+
1847 ================ ======================================================
1848 Attribute Description
1849 ================ ======================================================
1851 ================ ======================================================
1854 This actions is supported by
1855 ``OFPActionSetField(mpls_label=label)``
1856 in OpenFlow1.2 or later.
1860 actions += [parser.NXActionSetMplsLabel(label=0x10)]
1862 _subtype = nicira_ext.NXAST_SET_MPLS_LABEL
1869 type_=None, len_=None, vendor=None, subtype=None):
1870 super(NXActionSetMplsLabel, self).__init__()
1874 def parser(cls, buf):
1875 (label,) = struct.unpack_from(
1879 def serialize_body(self):
1881 msg_pack_into(self._fmt_str, data, 0,
1885 # For OpenFlow1.0 only
1886 class NXActionSetMplsTc(NXAction):
1890 This action sets the MPLS Tc.
1892 And equivalent to the followings action of ovs-ofctl command.
1898 +-------------------------+
1899 | **set_mpls_tc**\:\ *tc* |
1900 +-------------------------+
1902 ================ ======================================================
1903 Attribute Description
1904 ================ ======================================================
1906 ================ ======================================================
1909 This actions is supported by
1910 ``OFPActionSetField(mpls_label=tc)``
1911 in OpenFlow1.2 or later.
1915 actions += [parser.NXActionSetMplsLabel(tc=0x10)]
1917 _subtype = nicira_ext.NXAST_SET_MPLS_TC
1924 type_=None, len_=None, vendor=None, subtype=None):
1925 super(NXActionSetMplsTc, self).__init__()
1929 def parser(cls, buf):
1930 (tc,) = struct.unpack_from(
1934 def serialize_body(self):
1936 msg_pack_into(self._fmt_str, data, 0,
1940 class NXActionStackBase(NXAction):
1953 type_=None, len_=None, experimenter=None, subtype=None):
1954 super(NXActionStackBase, self).__init__()
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)
1967 def serialize_body(self):
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,
1974 six.binary_type(oxm_data),
1977 msg_pack_into("!%dx" % (12 - offset), data, offset)
1980 class NXActionStackPush(NXActionStackBase):
1984 This action pushes field to top of the stack.
1986 And equivalent to the followings action of ovs-ofctl command.
1989 pop:dst[start...end]
1992 +----------------------------------------------------+
1993 | **pop**\:\ *dst*\ **[**\ *start*\...\ *end*\ **]** |
1994 +----------------------------------------------------+
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 ================ ======================================================
2006 actions += [parser.NXActionStackPush(field="reg2",
2010 _subtype = nicira_ext.NXAST_STACK_PUSH
2012 class NXActionStackPop(NXActionStackBase):
2016 This action pops field from top of the stack.
2018 And equivalent to the followings action of ovs-ofctl command.
2021 pop:src[start...end]
2024 +----------------------------------------------------+
2025 | **pop**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
2026 +----------------------------------------------------+
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 ================ ======================================================
2038 actions += [parser.NXActionStackPop(field="reg2",
2042 _subtype = nicira_ext.NXAST_STACK_POP
2044 class NXActionSample(NXAction):
2046 Sample packets action
2048 This action samples packets and sends one sample for
2049 every sampled packet.
2051 And equivalent to the followings action of ovs-ofctl command.
2054 sample(argument[,argument]...)
2057 +----------------------------------------------------+
2058 | **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
2059 +----------------------------------------------------+
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
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 ================ ======================================================
2074 actions += [parser.NXActionSample(probability=3,
2079 _subtype = nicira_ext.NXAST_SAMPLE
2081 # probability, collector_set_id, obs_domain_id, obs_point_id
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
2097 def parser(cls, buf):
2101 obs_point_id) = struct.unpack_from(
2102 cls._fmt_str, buf, 0)
2103 return cls(probability,
2108 def serialize_body(self):
2110 msg_pack_into(self._fmt_str, data, 0,
2112 self.collector_set_id,
2117 class NXActionSample2(NXAction):
2119 Sample packets action
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.
2125 And equivalent to the followings action of ovs-ofctl command.
2128 sample(argument[,argument]...)
2131 +----------------------------------------------------+
2132 | **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
2133 +----------------------------------------------------+
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 ================ ======================================================
2148 actions += [parser.NXActionSample2(probability=3,
2152 sampling_port=8080)]
2154 _subtype = nicira_ext.NXAST_SAMPLE2
2156 # probability, collector_set_id, obs_domain_id,
2157 # obs_point_id, sampling_port
2158 _fmt_str = '!HIIIH6x'
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
2175 def parser(cls, buf):
2180 sampling_port) = struct.unpack_from(
2181 cls._fmt_str, buf, 0)
2182 return cls(probability,
2188 def serialize_body(self):
2190 msg_pack_into(self._fmt_str, data, 0,
2192 self.collector_set_id,
2198 class NXActionFinTimeout(NXAction):
2200 Change TCP timeout action
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.
2206 And equivalent to the followings action of ovs-ofctl command.
2209 fin_timeout(argument[,argument]...)
2212 +---------------------------------------------------------+
2213 | **fin_timeout(**\ *argument*\[,\ *argument*\]...\ **)** |
2214 +---------------------------------------------------------+
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 ================ ======================================================
2227 match = parser.OFPMatch(ip_proto=6, eth_type=0x0800)
2228 actions += [parser.NXActionFinTimeout(fin_idle_timeout=30,
2229 fin_hard_timeout=60)]
2231 _subtype = nicira_ext.NXAST_FIN_TIMEOUT
2233 # fin_idle_timeout, 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
2245 def parser(cls, buf):
2247 fin_hard_timeout) = struct.unpack_from(
2248 cls._fmt_str, buf, 0)
2249 return cls(fin_idle_timeout,
2252 def serialize_body(self):
2254 msg_pack_into(self._fmt_str, data, 0,
2255 self.fin_idle_timeout,
2256 self.fin_hard_timeout)
2259 class NXActionConjunction(NXAction):
2261 Conjunctive matches action
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.
2267 And equivalent to the followings action of ovs-ofctl command.
2273 +--------------------------------------------------+
2274 | **conjunction(**\ *id*\,\ *k*\ **/**\ *n*\ **)** |
2275 +--------------------------------------------------+
2277 ================ ======================================================
2278 Attribute Description
2279 ================ ======================================================
2280 clause Number assigned to the flow's dimension
2281 n_clauses Specify the conjunctive flow's match condition
2283 ================ ======================================================
2287 actions += [parser.NXActionConjunction(clause=1,
2291 _subtype = nicira_ext.NXAST_CONJUNCTION
2293 # clause, n_clauses, 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
2307 def parser(cls, buf):
2310 id_,) = struct.unpack_from(
2311 cls._fmt_str, buf, 0)
2312 return cls(clause, n_clauses, id_)
2314 def serialize_body(self):
2316 msg_pack_into(self._fmt_str, data, 0,
2322 class NXActionMultipath(NXAction):
2324 Select multipath link action
2326 This action selects multipath link based on the specified parameters.
2327 Please refer to the ovs-ofctl command manual for details.
2329 And equivalent to the followings action of ovs-ofctl command.
2332 multipath(fields, basis, algorithm, n_links, arg, dst[start..end])
2335 +-------------------------------------------------------------+
2336 | **multipath(**\ *fields*\, \ *basis*\, \ *algorithm*\, |
2337 | *n_links*\, \ *arg*\, \ *dst*\[\ *start*\..\ *end*\]\ **)** |
2338 +-------------------------------------------------------------+
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 ================ ======================================================
2355 actions += [parser.NXActionMultipath(
2356 fields=nicira_ext.NX_HASH_FIELDS_SYMMETRIC_L4,
2358 algorithm=nicira_ext.NX_MP_ALG_HRW,
2361 ofs_nbits=nicira_ext.ofs_nbits(4, 31),
2364 _subtype = nicira_ext.NXAST_MULTIPATH
2366 # fields, basis, algorithm, max_link,
2367 # arg, ofs_nbits, dst
2368 _fmt_str = '!HH2xHHI2xH4s'
2383 type_=None, len_=None, experimenter=None, subtype=None):
2384 super(NXActionMultipath, self).__init__()
2385 self.fields = fields
2387 self.algorithm = algorithm
2388 self.max_link = max_link
2390 self.ofs_nbits = ofs_nbits
2394 def parser(cls, buf):
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)
2413 def serialize_body(self):
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,
2425 six.binary_type(dst))
2429 class _NXActionBundleBase(NXAction):
2430 # algorithm, fields, basis, slave_type, n_slaves
2432 _fmt_str = '!HHHIHH'
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)
2440 self.algorithm = algorithm
2441 self.fields = fields
2443 self.slave_type = slave_type
2444 self.n_slaves = n_slaves
2445 self.ofs_nbits = ofs_nbits
2448 assert isinstance(slaves, (list, tuple))
2450 assert isinstance(s, six.integer_types)
2452 self.slaves = slaves
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)
2461 offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
2462 nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
2465 (n, len_) = ofp.oxm_parse_header(buf, offset)
2466 dst = ofp.oxm_to_user_header(n)
2468 slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
2469 nicira_ext.NX_ACTION_HEADER_0_SIZE)
2472 for i in range(0, n_slaves):
2473 s = struct.unpack_from('!H', buf, slave_offset)
2477 return cls(algorithm, fields, basis, slave_type,
2478 n_slaves, ofs_nbits, dst, slaves)
2480 def serialize_body(self):
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)
2488 pad_len = (utils.round_up(self.n_slaves, 4) -
2492 msg_pack_into('%dx' % pad_len * 2, data, slave_offset)
2494 msg_pack_into(self._fmt_str, data, 0,
2495 self.algorithm, self.fields, self.basis,
2496 self.slave_type, self.n_slaves,
2498 offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
2499 nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
2502 msg_pack_into('I', data, offset, self.dst)
2504 oxm_data = ofp.oxm_from_user_header(self.dst)
2505 ofp.oxm_serialize_header(oxm_data, data, offset)
2508 class NXActionBundle(_NXActionBundleBase):
2510 Select bundle link action
2512 This action selects bundle link based on the specified parameters.
2513 Please refer to the ovs-ofctl command manual for details.
2515 And equivalent to the followings action of ovs-ofctl command.
2518 bundle(fields, basis, algorithm, slave_type, slaves:[ s1, s2,...])
2521 +-----------------------------------------------------------+
2522 | **bundle(**\ *fields*\, \ *basis*\, \ *algorithm*\, |
2523 | *slave_type*\, \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** |
2524 +-----------------------------------------------------------+
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 ================ ======================================================
2542 actions += [parser.NXActionBundle(
2543 algorithm=nicira_ext.NX_MP_ALG_HRW,
2544 fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
2546 slave_type=nicira_ext.NXM_OF_IN_PORT,
2552 _subtype = nicira_ext.NXAST_BUNDLE
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)
2561 class NXActionBundleLoad(_NXActionBundleBase):
2563 Select bundle link action
2565 This action has the same behavior as the bundle action,
2567 Please refer to the ovs-ofctl command manual for details.
2569 And equivalent to the followings action of ovs-ofctl command.
2572 bundle_load(fields, basis, algorithm, slave_type,
2573 dst[start..end], slaves:[ s1, s2,...])
2576 +-----------------------------------------------------------+
2577 | **bundle_load(**\ *fields*\, \ *basis*\, \ *algorithm*\, |
2578 | *slave_type*\, \ *dst*\[\ *start*\... \*emd*\], |
2579 | \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** | |
2580 +-----------------------------------------------------------+
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 ================ ======================================================
2599 actions += [parser.NXActionBundleLoad(
2600 algorithm=nicira_ext.NX_MP_ALG_HRW,
2601 fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
2603 slave_type=nicira_ext.NXM_OF_IN_PORT,
2605 ofs_nbits=nicira_ext.ofs_nbits(4, 31),
2609 _subtype = nicira_ext.NXAST_BUNDLE_LOAD
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)
2622 class NXActionCT(NXAction):
2624 Pass traffic to the connection tracker action
2626 This action sends the packet through the connection tracker.
2628 And equivalent to the followings action of ovs-ofctl command.
2631 ct(argument[,argument]...)
2634 +------------------------------------------------+
2635 | **ct(**\ *argument*\[,\ *argument*\]...\ **)** |
2636 +------------------------------------------------+
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
2651 ================ ======================================================
2655 If you set number to zone_src,
2656 Traceback occurs when you run the to_jsondict.
2660 match = parser.OFPMatch(eth_type=0x0800, ct_state=(0,32))
2661 actions += [parser.NXActionCT(
2664 zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
2669 _subtype = nicira_ext.NXAST_CT
2671 # flags, zone_src, zone_ofs_nbits, recirc_table,
2673 _fmt_str = '!H4sHB3xH'
2680 # Followed by actions
2689 type_=None, len_=None, experimenter=None, subtype=None):
2690 super(NXActionCT, self).__init__()
2692 self.zone_src = zone_src
2693 self.zone_ofs_nbits = zone_ofs_nbits
2694 self.recirc_table = recirc_table
2696 self.actions = actions
2699 def parser(cls, buf):
2704 alg,) = struct.unpack_from(
2705 cls._fmt_str, buf, 0)
2706 rest = buf[struct.calcsize(cls._fmt_str):]
2709 if oxm_data == b'\x00' * 4:
2712 (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
2713 zone_src = ofp.oxm_to_user_header(n)
2717 while len(rest) > 0:
2718 action = ofpp.OFPAction.parser(rest, 0)
2719 actions.append(action)
2720 rest = rest[action.len:]
2722 return cls(flags, zone_src, zone_ofs_nbits, recirc_table,
2725 def serialize_body(self):
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)
2733 zone_src = bytearray()
2734 oxm = ofp.oxm_from_user_header(self.zone_src)
2735 ofp.oxm_serialize_header(oxm, zone_src, 0)
2737 msg_pack_into(self._fmt_str, data, 0,
2739 six.binary_type(zone_src),
2740 self.zone_ofs_nbits,
2743 for a in self.actions:
2744 a.serialize(data, len(data))
2747 class NXActionCTClear(NXAction):
2749 Clear connection tracking state action
2751 This action clears connection tracking state from packets.
2753 And equivalent to the followings action of ovs-ofctl command.
2765 actions += [parser.NXActionCTClear()]
2767 _subtype = nicira_ext.NXAST_CT_CLEAR
2772 type_=None, len_=None, experimenter=None, subtype=None):
2773 super(NXActionCTClear, self).__init__()
2776 def parser(cls, buf):
2779 def serialize_body(self):
2781 msg_pack_into(self._fmt_str, data, 0)
2784 class NXActionNAT(NXAction):
2786 Network address translation action
2788 This action sends the packet through the connection tracker.
2790 And equivalent to the followings action of ovs-ofctl command.
2793 The following command image does not exist in ovs-ofctl command
2794 manual and has been created from the command response.
2797 nat(src=ip_min-ip_max : proto_min-proto-max)
2800 +--------------------------------------------------+
2801 | **nat(src**\=\ *ip_min*\ **-**\ *ip_max*\ **:** |
2802 | *proto_min*\ **-**\ *proto-max*\ **)** |
2803 +--------------------------------------------------+
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 ================ ======================================================
2818 ``NXActionNAT`` must be defined in the actions in the
2823 match = parser.OFPMatch(eth_type=0x0800)
2828 zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
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
2845 _subtype = nicira_ext.NXAST_NAT
2847 # pad, flags, range_present
2849 # Followed by optional parameters
2866 range_proto_min=None,
2867 range_proto_max=None,
2868 type_=None, len_=None, experimenter=None, subtype=None):
2869 super(NXActionNAT, self).__init__()
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
2879 def parser(cls, buf):
2881 range_present) = struct.unpack_from(
2882 cls._fmt_str, buf, 0)
2883 rest = buf[struct.calcsize(cls._fmt_str):]
2884 # optional parameters
2886 if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MIN:
2887 kwargs['range_ipv4_min'] = type_desc.IPv4Addr.to_user(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])
2892 if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MIN:
2893 kwargs['range_ipv6_min'] = (
2894 type_desc.IPv6Addr.to_user(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]))
2900 if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MIN:
2901 kwargs['range_proto_min'] = type_desc.Int2.to_user(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])
2906 return cls(flags, **kwargs)
2908 def serialize_body(self):
2909 # Pack optional parameters first, as range_present needs
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)
2939 msg_pack_into(self._fmt_str, data, 0,
2942 msg_pack_into('!%ds' % len(optional_data), data, len(data),
2947 class NXActionOutputTrunc(NXAction):
2949 Truncate output action
2951 This action truncate a packet into the specified size and outputs it.
2953 And equivalent to the followings action of ovs-ofctl command.
2956 output(port=port,max_len=max_len)
2959 +--------------------------------------------------------------+
2960 | **output(port**\=\ *port*\,\ **max_len**\=\ *max_len*\ **)** |
2961 +--------------------------------------------------------------+
2963 ================ ======================================================
2964 Attribute Description
2965 ================ ======================================================
2967 max_len Max bytes to send
2968 ================ ======================================================
2972 actions += [parser.NXActionOutputTrunc(port=8080,
2975 _subtype = nicira_ext.NXAST_OUTPUT_TRUNC
2983 type_=None, len_=None, experimenter=None, subtype=None):
2984 super(NXActionOutputTrunc, self).__init__()
2986 self.max_len = max_len
2989 def parser(cls, buf):
2991 max_len) = struct.unpack_from(
2992 cls._fmt_str, buf, 0)
2993 return cls(port, max_len)
2995 def serialize_body(self):
2997 msg_pack_into(self._fmt_str, data, 0,
3002 class NXActionDecNshTtl(NXAction):
3004 Decrement NSH TTL action
3006 This action decrements the TTL in the Network Service Header(NSH).
3008 This action was added in OVS v2.9.
3010 And equivalent to the followings action of ovs-ofctl command.
3018 actions += [parser.NXActionDecNshTtl()]
3020 _subtype = nicira_ext.NXAST_DEC_NSH_TTL
3025 type_=None, len_=None, vendor=None, subtype=None):
3026 super(NXActionDecNshTtl, self).__init__()
3029 def parser(cls, buf):
3032 def serialize_body(self):
3034 msg_pack_into(self._fmt_str, data, 0)
3038 v.__module__ = ofpp.__name__ # Necessary for stringify stuff
3041 add_attr('NXAction', NXAction)
3042 add_attr('NXActionUnknown', NXActionUnknown)
3050 'NXActionSetTunnel',
3051 'NXActionSetTunnel64',
3054 'NXActionResubmitTable',
3055 'NXActionOutputReg',
3056 'NXActionOutputReg2',
3060 'NXActionController',
3061 'NXActionController2',
3062 'NXActionDecTtlCntIds',
3065 'NXActionSetMplsTtl',
3066 'NXActionDecMplsTtl',
3067 'NXActionSetMplsLabel',
3068 'NXActionSetMplsTc',
3069 'NXActionStackPush',
3073 'NXActionFinTimeout',
3074 'NXActionConjunction',
3075 'NXActionMultipath',
3077 'NXActionBundleLoad',
3081 'NXActionOutputTrunc',
3082 '_NXFlowSpec', # exported for testing
3086 'NXActionDecNshTtl',
3089 for name in classes:
3092 if issubclass(cls, NXAction):
3093 NXAction.register(cls)
3094 if issubclass(cls, _NXFlowSpec):
3095 _NXFlowSpec.register(cls)