os-ken/ryu/ofproto/nx_actions.py

3118 lines
104 KiB
Python

# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
# Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import six
import struct
from ryu import utils
from ryu.lib import type_desc
from ryu.ofproto import nicira_ext
from ryu.ofproto import ofproto_common
from ryu.lib.pack_utils import msg_pack_into
from ryu.ofproto.ofproto_parser import StringifyMixin
def generate(ofp_name, ofpp_name):
import sys
ofp = sys.modules[ofp_name]
ofpp = sys.modules[ofpp_name]
class _NXFlowSpec(StringifyMixin):
_hdr_fmt_str = '!H' # 2 bit 0s, 1 bit src, 2 bit dst, 11 bit n_bits
_dst_type = None
_subclasses = {}
_TYPE = {
'nx-flow-spec-field': [
'src',
'dst',
]
}
def __init__(self, src, dst, n_bits):
self.src = src
self.dst = dst
self.n_bits = n_bits
@classmethod
def register(cls, subcls):
assert issubclass(subcls, cls)
assert subcls._dst_type not in cls._subclasses
cls._subclasses[subcls._dst_type] = subcls
@classmethod
def parse(cls, buf):
(hdr,) = struct.unpack_from(cls._hdr_fmt_str, buf, 0)
rest = buf[struct.calcsize(cls._hdr_fmt_str):]
if hdr == 0:
return None, rest # all-0 header is no-op for padding
src_type = (hdr >> 13) & 0x1
dst_type = (hdr >> 11) & 0x3
n_bits = hdr & 0x3ff
subcls = cls._subclasses[dst_type]
if src_type == 0: # subfield
src = cls._parse_subfield(rest)
rest = rest[6:]
elif src_type == 1: # immediate
src_len = (n_bits + 15) // 16 * 2
src_bin = rest[:src_len]
src = type_desc.IntDescr(size=src_len).to_user(src_bin)
rest = rest[src_len:]
if dst_type == 0: # match
dst = cls._parse_subfield(rest)
rest = rest[6:]
elif dst_type == 1: # load
dst = cls._parse_subfield(rest)
rest = rest[6:]
elif dst_type == 2: # output
dst = '' # empty
return subcls(src=src, dst=dst, n_bits=n_bits), rest
def serialize(self):
buf = bytearray()
if isinstance(self.src, tuple):
src_type = 0 # subfield
else:
src_type = 1 # immediate
# header
val = (src_type << 13) | (self._dst_type << 11) | self.n_bits
msg_pack_into(self._hdr_fmt_str, buf, 0, val)
# src
if src_type == 0: # subfield
buf += self._serialize_subfield(self.src)
elif src_type == 1: # immediate
src_len = (self.n_bits + 15) // 16 * 2
buf += type_desc.IntDescr(size=src_len).from_user(self.src)
# dst
if self._dst_type == 0: # match
buf += self._serialize_subfield(self.dst)
elif self._dst_type == 1: # load
buf += self._serialize_subfield(self.dst)
elif self._dst_type == 2: # output
pass # empty
return buf
@staticmethod
def _parse_subfield(buf):
(n, len) = ofp.oxm_parse_header(buf, 0)
assert len == 4 # only 4-bytes NXM/OXM are defined
field = ofp.oxm_to_user_header(n)
rest = buf[len:]
(ofs,) = struct.unpack_from('!H', rest, 0)
return (field, ofs)
@staticmethod
def _serialize_subfield(subfield):
(field, ofs) = subfield
buf = bytearray()
n = ofp.oxm_from_user_header(field)
ofp.oxm_serialize_header(n, buf, 0)
assert len(buf) == 4 # only 4-bytes NXM/OXM are defined
msg_pack_into('!H', buf, 4, ofs)
return buf
class NXFlowSpecMatch(_NXFlowSpec):
"""
Specification for adding match criterion
This class is used by ``NXActionLearn``.
For the usage of this class, please refer to ``NXActionLearn``.
================ ======================================================
Attribute Description
================ ======================================================
src OXM/NXM header and Start bit for source field
dst OXM/NXM header and Start bit for destination field
n_bits The number of bits from the start bit
================ ======================================================
"""
# Add a match criteria
# an example of the corresponding ovs-ofctl syntax:
# NXM_OF_VLAN_TCI[0..11]
_dst_type = 0
class NXFlowSpecLoad(_NXFlowSpec):
"""
Add NXAST_REG_LOAD actions
This class is used by ``NXActionLearn``.
For the usage of this class, please refer to ``NXActionLearn``.
================ ======================================================
Attribute Description
================ ======================================================
src OXM/NXM header and Start bit for source field
dst OXM/NXM header and Start bit for destination field
n_bits The number of bits from the start bit
================ ======================================================
"""
# Add NXAST_REG_LOAD actions
# an example of the corresponding ovs-ofctl syntax:
# NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
_dst_type = 1
class NXFlowSpecOutput(_NXFlowSpec):
"""
Add an OFPAT_OUTPUT action
This class is used by ``NXActionLearn``.
For the usage of this class, please refer to ``NXActionLearn``.
================ ======================================================
Attribute Description
================ ======================================================
src OXM/NXM header and Start bit for source field
dst Must be ''
n_bits The number of bits from the start bit
================ ======================================================
"""
# Add an OFPAT_OUTPUT action
# an example of the corresponding ovs-ofctl syntax:
# output:NXM_OF_IN_PORT[]
_dst_type = 2
def __init__(self, src, n_bits, dst=''):
assert dst == ''
super(NXFlowSpecOutput, self).__init__(src=src, dst=dst,
n_bits=n_bits)
class NXAction(ofpp.OFPActionExperimenter):
_fmt_str = '!H' # subtype
_subtypes = {}
_experimenter = ofproto_common.NX_EXPERIMENTER_ID
def __init__(self):
super(NXAction, self).__init__(self._experimenter)
self.subtype = self._subtype
@classmethod
def parse(cls, buf):
fmt_str = NXAction._fmt_str
(subtype,) = struct.unpack_from(fmt_str, buf, 0)
subtype_cls = cls._subtypes.get(subtype)
rest = buf[struct.calcsize(fmt_str):]
if subtype_cls is None:
return NXActionUnknown(subtype, rest)
return subtype_cls.parser(rest)
def serialize(self, buf, offset):
data = self.serialize_body()
payload_offset = (
ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE +
struct.calcsize(NXAction._fmt_str)
)
self.len = utils.round_up(payload_offset + len(data), 8)
super(NXAction, self).serialize(buf, offset)
msg_pack_into(NXAction._fmt_str,
buf,
offset + ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE,
self.subtype)
buf += data
@classmethod
def register(cls, subtype_cls):
assert subtype_cls._subtype is not cls._subtypes
cls._subtypes[subtype_cls._subtype] = subtype_cls
class NXActionUnknown(NXAction):
def __init__(self, subtype, data=None,
type_=None, len_=None, experimenter=None):
self._subtype = subtype
super(NXActionUnknown, self).__init__()
self.data = data
@classmethod
def parser(cls, buf):
return cls(data=buf)
def serialize_body(self):
# fixup
return bytearray() if self.data is None else self.data
# For OpenFlow1.0 only
class NXActionSetQueue(NXAction):
r"""
Set queue action
This action sets the queue that should be used to queue
when packets are output.
And equivalent to the followings action of ovs-ofctl command.
..
set_queue:queue
..
+-------------------------+
| **set_queue**\:\ *queue*|
+-------------------------+
================ ======================================================
Attribute Description
================ ======================================================
queue_id Queue ID for the packets
================ ======================================================
.. note::
This actions is supported by
``OFPActionSetQueue``
in OpenFlow1.2 or later.
Example::
actions += [parser.NXActionSetQueue(queue_id=10)]
"""
_subtype = nicira_ext.NXAST_SET_QUEUE
# queue_id
_fmt_str = '!2xI'
def __init__(self, queue_id,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionSetQueue, self).__init__()
self.queue_id = queue_id
@classmethod
def parser(cls, buf):
(queue_id,) = struct.unpack_from(cls._fmt_str, buf, 0)
return cls(queue_id)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0, self.queue_id)
return data
class NXActionPopQueue(NXAction):
"""
Pop queue action
This action restors the queue to the value it was before any
set_queue actions were applied.
And equivalent to the followings action of ovs-ofctl command.
..
pop_queue
..
+---------------+
| **pop_queue** |
+---------------+
Example::
actions += [parser.NXActionPopQueue()]
"""
_subtype = nicira_ext.NXAST_POP_QUEUE
_fmt_str = '!6x'
def __init__(self,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionPopQueue, self).__init__()
@classmethod
def parser(cls, buf):
return cls()
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0)
return data
class NXActionRegLoad(NXAction):
r"""
Load literal value action
This action loads a literal value into a field or part of a field.
And equivalent to the followings action of ovs-ofctl command.
..
load:value->dst[start..end]
..
+-----------------------------------------------------------------+
| **load**\:\ *value*\->\ *dst*\ **[**\ *start*\..\ *end*\ **]** |
+-----------------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
ofs_nbits Start and End for the OXM/NXM field.
Setting method refer to the ``nicira_ext.ofs_nbits``
dst OXM/NXM header for destination field
value OXM/NXM value to be loaded
================ ======================================================
Example::
actions += [parser.NXActionRegLoad(
ofs_nbits=nicira_ext.ofs_nbits(4, 31),
dst="eth_dst",
value=0x112233)]
"""
_subtype = nicira_ext.NXAST_REG_LOAD
_fmt_str = '!HIQ' # ofs_nbits, dst, value
_TYPE = {
'ascii': [
'dst',
]
}
def __init__(self, ofs_nbits, dst, value,
type_=None, len_=None, experimenter=None,
subtype=None):
super(NXActionRegLoad, self).__init__()
self.ofs_nbits = ofs_nbits
self.dst = dst
self.value = value
@classmethod
def parser(cls, buf):
(ofs_nbits, dst, value,) = struct.unpack_from(
cls._fmt_str, buf, 0)
# Right-shift instead of using oxm_parse_header for simplicity...
dst_name = ofp.oxm_to_user_header(dst >> 9)
return cls(ofs_nbits, dst_name, value)
def serialize_body(self):
hdr_data = bytearray()
n = ofp.oxm_from_user_header(self.dst)
ofp.oxm_serialize_header(n, hdr_data, 0)
(dst_num,) = struct.unpack_from('!I', six.binary_type(hdr_data), 0)
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.ofs_nbits, dst_num, self.value)
return data
class NXActionRegLoad2(NXAction):
r"""
Load literal value action
This action loads a literal value into a field or part of a field.
And equivalent to the followings action of ovs-ofctl command.
..
set_field:value[/mask]->dst
..
+------------------------------------------------------------+
| **set_field**\:\ *value*\ **[**\/\ *mask*\ **]**\->\ *dst* |
+------------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
value OXM/NXM value to be loaded
mask Mask for destination field
dst OXM/NXM header for destination field
================ ======================================================
Example::
actions += [parser.NXActionRegLoad2(dst="tun_ipv4_src",
value="192.168.10.0",
mask="255.255.255.0")]
"""
_subtype = nicira_ext.NXAST_REG_LOAD2
_TYPE = {
'ascii': [
'dst',
'value',
]
}
def __init__(self, dst, value, mask=None,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionRegLoad2, self).__init__()
self.dst = dst
self.value = value
self.mask = mask
@classmethod
def parser(cls, buf):
(n, uv, mask, _len) = ofp.oxm_parse(buf, 0)
dst, value = ofp.oxm_to_user(n, uv, mask)
if isinstance(value, (tuple, list)):
return cls(dst, value[0], value[1])
else:
return cls(dst, value, None)
def serialize_body(self):
data = bytearray()
if self.mask is None:
value = self.value
else:
value = (self.value, self.mask)
self._TYPE['ascii'].append('mask')
n, value, mask = ofp.oxm_from_user(self.dst, value)
len_ = ofp.oxm_serialize(n, value, mask, data, 0)
msg_pack_into("!%dx" % (14 - len_), data, len_)
return data
class NXActionNote(NXAction):
r"""
Note action
This action does nothing at all.
And equivalent to the followings action of ovs-ofctl command.
..
note:[hh]..
..
+-----------------------------------+
| **note**\:\ **[**\ *hh*\ **]**\.. |
+-----------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
note A list of integer type values
================ ======================================================
Example::
actions += [parser.NXActionNote(note=[0xaa,0xbb,0xcc,0xdd])]
"""
_subtype = nicira_ext.NXAST_NOTE
# note
_fmt_str = '!%dB'
# set the integer array in a note
def __init__(self,
note,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionNote, self).__init__()
self.note = note
@classmethod
def parser(cls, buf):
note = struct.unpack_from(
cls._fmt_str % len(buf), buf, 0)
return cls(list(note))
def serialize_body(self):
assert isinstance(self.note, (tuple, list))
for n in self.note:
assert isinstance(n, six.integer_types)
pad = (len(self.note) + nicira_ext.NX_ACTION_HEADER_0_SIZE) % 8
if pad:
self.note += [0x0 for i in range(8 - pad)]
note_len = len(self.note)
data = bytearray()
msg_pack_into(self._fmt_str % note_len, data, 0,
*self.note)
return data
class _NXActionSetTunnelBase(NXAction):
# _subtype, _fmt_str must be attributes of subclass.
def __init__(self,
tun_id,
type_=None, len_=None, experimenter=None, subtype=None):
super(_NXActionSetTunnelBase, self).__init__()
self.tun_id = tun_id
@classmethod
def parser(cls, buf):
(tun_id,) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(tun_id)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.tun_id)
return data
class NXActionSetTunnel(_NXActionSetTunnelBase):
r"""
Set Tunnel action
This action sets the identifier (such as GRE) to the specified id.
And equivalent to the followings action of ovs-ofctl command.
.. note::
ovs-ofctl command of the OpenFlow1.0 is different from that
of OpenFlow1.2 or later.
OpenFlow1.0
..
set_tunnel:id
..
+------------------------+
| **set_tunnel**\:\ *id* |
+------------------------+
OpenFlow1.2 or later
..
set_field:value->tun_id
..
+-----------------------------------+
| **set_field**\:\ *value*\->tun_id |
+-----------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
tun_id Tunnel ID(32bits)
================ ======================================================
Example::
actions += [parser.NXActionSetTunnel(tun_id=0xa)]
"""
_subtype = nicira_ext.NXAST_SET_TUNNEL
# tun_id
_fmt_str = '!2xI'
class NXActionSetTunnel64(_NXActionSetTunnelBase):
r"""
Set Tunnel action
This action outputs to a port that encapsulates
the packet in a tunnel.
And equivalent to the followings action of ovs-ofctl command.
.. note::
ovs-ofctl command of the OpenFlow1.0 is different from that
of OpenFlow1.2 or later.
OpenFlow1.0
..
set_tunnel64:id
..
+--------------------------+
| **set_tunnel64**\:\ *id* |
+--------------------------+
OpenFlow1.2 or later
..
set_field:value->tun_id
..
+-----------------------------------+
| **set_field**\:\ *value*\->tun_id |
+-----------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
tun_id Tunnel ID(64bits)
================ ======================================================
Example::
actions += [parser.NXActionSetTunnel64(tun_id=0xa)]
"""
_subtype = nicira_ext.NXAST_SET_TUNNEL64
# tun_id
_fmt_str = '!6xQ'
class NXActionRegMove(NXAction):
r"""
Move register action
This action copies the src to dst.
And equivalent to the followings action of ovs-ofctl command.
..
move:src[start..end]->dst[start..end]
..
+--------------------------------------------------------+
| **move**\:\ *src*\ **[**\ *start*\..\ *end*\ **]**\->\ |
| *dst*\ **[**\ *start*\..\ *end* \ **]** |
+--------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
src_field OXM/NXM header for source field
dst_field OXM/NXM header for destination field
n_bits Number of bits
src_ofs Starting bit offset in source
dst_ofs Starting bit offset in destination
================ ======================================================
.. CAUTION::
**src_start**\ and \ **src_end**\ difference and \ **dst_start**\
and \ **dst_end**\ difference must be the same.
Example::
actions += [parser.NXActionRegMove(src_field="reg0",
dst_field="reg1",
n_bits=5,
src_ofs=0
dst_ofs=10)]
"""
_subtype = nicira_ext.NXAST_REG_MOVE
_fmt_str = '!HHH' # n_bits, src_ofs, dst_ofs
# Followed by OXM fields (src, dst) and padding to 8 bytes boundary
_TYPE = {
'ascii': [
'src_field',
'dst_field',
]
}
def __init__(self, src_field, dst_field, n_bits, src_ofs=0, dst_ofs=0,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionRegMove, self).__init__()
self.n_bits = n_bits
self.src_ofs = src_ofs
self.dst_ofs = dst_ofs
self.src_field = src_field
self.dst_field = dst_field
@classmethod
def parser(cls, buf):
(n_bits, src_ofs, dst_ofs,) = struct.unpack_from(
cls._fmt_str, buf, 0)
rest = buf[struct.calcsize(NXActionRegMove._fmt_str):]
# src field
(n, len) = ofp.oxm_parse_header(rest, 0)
src_field = ofp.oxm_to_user_header(n)
rest = rest[len:]
# dst field
(n, len) = ofp.oxm_parse_header(rest, 0)
dst_field = ofp.oxm_to_user_header(n)
rest = rest[len:]
# ignore padding
return cls(src_field, dst_field=dst_field, n_bits=n_bits,
src_ofs=src_ofs, dst_ofs=dst_ofs)
def serialize_body(self):
# fixup
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.n_bits, self.src_ofs, self.dst_ofs)
# src field
n = ofp.oxm_from_user_header(self.src_field)
ofp.oxm_serialize_header(n, data, len(data))
# dst field
n = ofp.oxm_from_user_header(self.dst_field)
ofp.oxm_serialize_header(n, data, len(data))
return data
class NXActionResubmit(NXAction):
r"""
Resubmit action
This action searches one of the switch's flow tables.
And equivalent to the followings action of ovs-ofctl command.
..
resubmit:port
..
+------------------------+
| **resubmit**\:\ *port* |
+------------------------+
================ ======================================================
Attribute Description
================ ======================================================
in_port New in_port for checking flow table
================ ======================================================
Example::
actions += [parser.NXActionResubmit(in_port=8080)]
"""
_subtype = nicira_ext.NXAST_RESUBMIT
# in_port
_fmt_str = '!H4x'
def __init__(self,
in_port=0xfff8,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionResubmit, self).__init__()
self.in_port = in_port
@classmethod
def parser(cls, buf):
(in_port,) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(in_port)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.in_port)
return data
class NXActionResubmitTable(NXAction):
r"""
Resubmit action
This action searches one of the switch's flow tables.
And equivalent to the followings action of ovs-ofctl command.
..
resubmit([port],[table])
..
+------------------------------------------------+
| **resubmit(**\[\ *port*\]\,[\ *table*\]\ **)** |
+------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
in_port New in_port for checking flow table
table_id Checking flow tables
================ ======================================================
Example::
actions += [parser.NXActionResubmit(in_port=8080,
table_id=10)]
"""
_subtype = nicira_ext.NXAST_RESUBMIT_TABLE
# in_port, table_id
_fmt_str = '!HB3x'
def __init__(self,
in_port=0xfff8,
table_id=0xff,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionResubmitTable, self).__init__()
self.in_port = in_port
self.table_id = table_id
@classmethod
def parser(cls, buf):
(in_port,
table_id) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(in_port, table_id)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.in_port, self.table_id)
return data
class NXActionOutputReg(NXAction):
r"""
Add output action
This action outputs the packet to the OpenFlow port number read from
src.
And equivalent to the followings action of ovs-ofctl command.
..
output:src[start...end]
..
+-------------------------------------------------------+
| **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
+-------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
ofs_nbits Start and End for the OXM/NXM field.
Setting method refer to the ``nicira_ext.ofs_nbits``
src OXM/NXM header for source field
max_len Max length to send to controller
================ ======================================================
Example::
actions += [parser.NXActionOutputReg(
ofs_nbits=nicira_ext.ofs_nbits(4, 31),
src="reg0",
max_len=1024)]
"""
_subtype = nicira_ext.NXAST_OUTPUT_REG
# ofs_nbits, src, max_len
_fmt_str = '!H4sH6x'
_TYPE = {
'ascii': [
'src',
]
}
def __init__(self,
ofs_nbits,
src,
max_len,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionOutputReg, self).__init__()
self.ofs_nbits = ofs_nbits
self.src = src
self.max_len = max_len
@classmethod
def parser(cls, buf):
(ofs_nbits, oxm_data, max_len) = struct.unpack_from(
cls._fmt_str, buf, 0)
(n, len_) = ofp.oxm_parse_header(oxm_data, 0)
src = ofp.oxm_to_user_header(n)
return cls(ofs_nbits,
src,
max_len)
def serialize_body(self):
data = bytearray()
src = bytearray()
oxm = ofp.oxm_from_user_header(self.src)
ofp.oxm_serialize_header(oxm, src, 0),
msg_pack_into(self._fmt_str, data, 0,
self.ofs_nbits,
six.binary_type(src),
self.max_len)
return data
class NXActionOutputReg2(NXAction):
r"""
Add output action
This action outputs the packet to the OpenFlow port number read from
src.
And equivalent to the followings action of ovs-ofctl command.
..
output:src[start...end]
..
+-------------------------------------------------------+
| **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
+-------------------------------------------------------+
.. NOTE::
Like the ``NXActionOutputReg`` but organized so
that there is room for a 64-bit experimenter OXM as 'src'.
================ ======================================================
Attribute Description
================ ======================================================
ofs_nbits Start and End for the OXM/NXM field.
Setting method refer to the ``nicira_ext.ofs_nbits``
src OXM/NXM header for source field
max_len Max length to send to controller
================ ======================================================
Example::
actions += [parser.NXActionOutputReg2(
ofs_nbits=nicira_ext.ofs_nbits(4, 31),
src="reg0",
max_len=1024)]
"""
_subtype = nicira_ext.NXAST_OUTPUT_REG2
# ofs_nbits, src, max_len
_fmt_str = '!HH4s'
_TYPE = {
'ascii': [
'src',
]
}
def __init__(self,
ofs_nbits,
src,
max_len,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionOutputReg2, self).__init__()
self.ofs_nbits = ofs_nbits
self.src = src
self.max_len = max_len
@classmethod
def parser(cls, buf):
(ofs_nbits,
max_len,
oxm_data) = struct.unpack_from(
cls._fmt_str, buf, 0)
(n, len_) = ofp.oxm_parse_header(oxm_data, 0)
src = ofp.oxm_to_user_header(n)
return cls(ofs_nbits,
src,
max_len)
def serialize_body(self):
data = bytearray()
oxm_data = bytearray()
oxm = ofp.oxm_from_user_header(self.src)
ofp.oxm_serialize_header(oxm, oxm_data, 0),
msg_pack_into(self._fmt_str, data, 0,
self.ofs_nbits,
self.max_len,
six.binary_type(oxm_data))
offset = len(data)
msg_pack_into("!%dx" % (14 - offset), data, offset)
return data
class NXActionLearn(NXAction):
r"""
Adds or modifies flow action
This action adds or modifies a flow in OpenFlow table.
And equivalent to the followings action of ovs-ofctl command.
..
learn(argument[,argument]...)
..
+---------------------------------------------------+
| **learn(**\ *argument*\[,\ *argument*\]...\ **)** |
+---------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
table_id The table in which the new flow should be inserted
specs Adds a match criterion to the new flow
Please use the
``NXFlowSpecMatch``
in order to set the following format
..
field=value
field[start..end]=src[start..end]
field[start..end]
..
| *field*\=\ *value*
| *field*\ **[**\ *start*\..\ *end*\ **]**\ =\
*src*\ **[**\ *start*\..\ *end*\ **]**
| *field*\ **[**\ *start*\..\ *end*\ **]**
|
Please use the
``NXFlowSpecLoad``
in order to set the following format
..
load:value->dst[start..end]
load:src[start..end]->dst[start..end]
..
| **load**\:\ *value*\ **->**\ *dst*\
**[**\ *start*\..\ *end*\ **]**
| **load**\:\ *src*\ **[**\ *start*\..\ *end*\
**] ->**\ *dst*\ **[**\ *start*\..\ *end*\ **]**
|
Please use the
``NXFlowSpecOutput``
in order to set the following format
..
output:field[start..end]
..
| **output:**\ field\ **[**\ *start*\..\ *end*\ **]**
idle_timeout Idle time before discarding(seconds)
hard_timeout Max time before discarding(seconds)
priority Priority level of flow entry
cookie Cookie for new flow
flags send_flow_rem
fin_idle_timeout Idle timeout after FIN(seconds)
fin_hard_timeout Hard timeout after FIN(seconds)
================ ======================================================
.. CAUTION::
The arguments specify the flow's match fields, actions,
and other properties, as follows.
At least one match criterion and one action argument
should ordinarily be specified.
Example::
actions += [
parser.NXActionLearn(able_id=10,
specs=[parser.NXFlowSpecMatch(src=0x800,
dst=('eth_type_nxm', 0),
n_bits=16),
parser.NXFlowSpecMatch(src=('reg1', 1),
dst=('reg2', 3),
n_bits=5),
parser.NXFlowSpecMatch(src=('reg3', 1),
dst=('reg3', 1),
n_bits=5),
parser.NXFlowSpecLoad(src=0,
dst=('reg4', 3),
n_bits=5),
parser.NXFlowSpecLoad(src=('reg5', 1),
dst=('reg6', 3),
n_bits=5),
parser.NXFlowSpecOutput(src=('reg7', 1),
dst="",
n_bits=5)],
idle_timeout=180,
hard_timeout=300,
priority=1,
cookie=0x64,
flags=ofproto.OFPFF_SEND_FLOW_REM,
fin_idle_timeout=180,
fin_hard_timeout=300)]
"""
_subtype = nicira_ext.NXAST_LEARN
# idle_timeout, hard_timeout, priority, cookie, flags,
# table_id, pad, fin_idle_timeout, fin_hard_timeout
_fmt_str = '!HHHQHBxHH'
# Followed by flow_mod_specs
def __init__(self,
table_id,
specs,
idle_timeout=0,
hard_timeout=0,
priority=ofp.OFP_DEFAULT_PRIORITY,
cookie=0,
flags=0,
fin_idle_timeout=0,
fin_hard_timeout=0,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionLearn, self).__init__()
self.idle_timeout = idle_timeout
self.hard_timeout = hard_timeout
self.priority = priority
self.cookie = cookie
self.flags = flags
self.table_id = table_id
self.fin_idle_timeout = fin_idle_timeout
self.fin_hard_timeout = fin_hard_timeout
self.specs = specs
@classmethod
def parser(cls, buf):
(idle_timeout,
hard_timeout,
priority,
cookie,
flags,
table_id,
fin_idle_timeout,
fin_hard_timeout,) = struct.unpack_from(
cls._fmt_str, buf, 0)
rest = buf[struct.calcsize(cls._fmt_str):]
# specs
specs = []
while len(rest) > 0:
spec, rest = _NXFlowSpec.parse(rest)
if spec is None:
continue
specs.append(spec)
return cls(idle_timeout=idle_timeout,
hard_timeout=hard_timeout,
priority=priority,
cookie=cookie,
flags=flags,
table_id=table_id,
fin_idle_timeout=fin_idle_timeout,
fin_hard_timeout=fin_hard_timeout,
specs=specs)
def serialize_body(self):
# fixup
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.idle_timeout,
self.hard_timeout,
self.priority,
self.cookie,
self.flags,
self.table_id,
self.fin_idle_timeout,
self.fin_hard_timeout)
for spec in self.specs:
data += spec.serialize()
return data
class NXActionExit(NXAction):
"""
Halt action
This action causes OpenvSwitch to immediately halt
execution of further actions.
And equivalent to the followings action of ovs-ofctl command.
..
exit
..
+----------+
| **exit** |
+----------+
Example::
actions += [parser.NXActionExit()]
"""
_subtype = nicira_ext.NXAST_EXIT
_fmt_str = '!6x'
def __init__(self,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionExit, self).__init__()
@classmethod
def parser(cls, buf):
return cls()
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0)
return data
# For OpenFlow1.0 only
class NXActionDecTtl(NXAction):
"""
Decrement IP TTL action
This action decrements TTL of IPv4 packet or
hop limit of IPv6 packet.
And equivalent to the followings action of ovs-ofctl command.
..
dec_ttl
..
+-------------+
| **dec_ttl** |
+-------------+
.. NOTE::
This actions is supported by
``OFPActionDecNwTtl``
in OpenFlow1.2 or later.
Example::
actions += [parser.NXActionDecTtl()]
"""
_subtype = nicira_ext.NXAST_DEC_TTL
_fmt_str = '!6x'
def __init__(self,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionDecTtl, self).__init__()
@classmethod
def parser(cls, buf):
return cls()
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0)
return data
class NXActionController(NXAction):
r"""
Send packet in message action
This action sends the packet to the OpenFlow controller as
a packet in message.
And equivalent to the followings action of ovs-ofctl command.
..
controller(key=value...)
..
+----------------------------------------------+
| **controller(**\ *key*\=\ *value*\...\ **)** |
+----------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
max_len Max length to send to controller
controller_id Controller ID to send packet-in
reason Reason for sending the message
================ ======================================================
Example::
actions += [
parser.NXActionController(max_len=1024,
controller_id=1,
reason=ofproto.OFPR_INVALID_TTL)]
"""
_subtype = nicira_ext.NXAST_CONTROLLER
# max_len, controller_id, reason
_fmt_str = '!HHBx'
def __init__(self,
max_len,
controller_id,
reason,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionController, self).__init__()
self.max_len = max_len
self.controller_id = controller_id
self.reason = reason
@classmethod
def parser(cls, buf):
(max_len,
controller_id,
reason) = struct.unpack_from(
cls._fmt_str, buf)
return cls(max_len,
controller_id,
reason)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.max_len,
self.controller_id,
self.reason)
return data
class NXActionController2(NXAction):
r"""
Send packet in message action
This action sends the packet to the OpenFlow controller as
a packet in message.
And equivalent to the followings action of ovs-ofctl command.
..
controller(key=value...)
..
+----------------------------------------------+
| **controller(**\ *key*\=\ *value*\...\ **)** |
+----------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
max_len Max length to send to controller
controller_id Controller ID to send packet-in
reason Reason for sending the message
userdata Additional data to the controller in the packet-in
message
pause Flag to pause pipeline to resume later
================ ======================================================
Example::
actions += [
parser.NXActionController(max_len=1024,
controller_id=1,
reason=ofproto.OFPR_INVALID_TTL,
userdata=[0xa,0xb,0xc],
pause=True)]
"""
_subtype = nicira_ext.NXAST_CONTROLLER2
_fmt_str = '!6x'
_PACK_STR = '!HH'
def __init__(self,
type_=None, len_=None, vendor=None, subtype=None,
**kwargs):
super(NXActionController2, self).__init__()
for arg in kwargs:
if arg in NXActionController2Prop._NAMES:
setattr(self, arg, kwargs[arg])
@classmethod
def parser(cls, buf):
cls_data = {}
offset = 6
buf_len = len(buf)
while buf_len > offset:
(type_, length) = struct.unpack_from(cls._PACK_STR, buf, offset)
offset += 4
try:
subcls = NXActionController2Prop._TYPES[type_]
except KeyError:
subcls = NXActionController2PropUnknown
data, size = subcls.parser_prop(buf[offset:], length - 4)
offset += size
cls_data[subcls._arg_name] = data
return cls(**cls_data)
def serialize_body(self):
body = bytearray()
msg_pack_into(self._fmt_str, body, 0)
prop_list = []
for arg in self.__dict__:
if arg in NXActionController2Prop._NAMES:
prop_list.append((NXActionController2Prop._NAMES[arg],
self.__dict__[arg]))
prop_list.sort(key=lambda x: x[0].type)
for subcls, value in prop_list:
body += subcls.serialize_prop(value)
return body
class NXActionController2Prop(object):
_TYPES = {}
_NAMES = {}
@classmethod
def register_type(cls, type_):
def _register_type(subcls):
subcls.type = type_
NXActionController2Prop._TYPES[type_] = subcls
NXActionController2Prop._NAMES[subcls._arg_name] = subcls
return subcls
return _register_type
class NXActionController2PropUnknown(NXActionController2Prop):
@classmethod
def parser_prop(cls, buf, length):
size = 4
return buf, size
@classmethod
def serialize_prop(cls, argment):
data = bytearray()
return data
@NXActionController2Prop.register_type(nicira_ext.NXAC2PT_MAX_LEN)
class NXActionController2PropMaxLen(NXActionController2Prop):
# max_len
_fmt_str = "!H2x"
_arg_name = "max_len"
@classmethod
def parser_prop(cls, buf, length):
size = 4
(max_len,) = struct.unpack_from(
cls._fmt_str, buf, 0)
return max_len, size
@classmethod
def serialize_prop(cls, max_len):
data = bytearray()
msg_pack_into("!HHH2x", data, 0,
nicira_ext.NXAC2PT_MAX_LEN,
8,
max_len)
return data
@NXActionController2Prop.register_type(nicira_ext.NXAC2PT_CONTROLLER_ID)
class NXActionController2PropControllerId(NXActionController2Prop):
# controller_id
_fmt_str = "!H2x"
_arg_name = "controller_id"
@classmethod
def parser_prop(cls, buf, length):
size = 4
(controller_id,) = struct.unpack_from(
cls._fmt_str, buf, 0)
return controller_id, size
@classmethod
def serialize_prop(cls, controller_id):
data = bytearray()
msg_pack_into("!HHH2x", data, 0,
nicira_ext.NXAC2PT_CONTROLLER_ID,
8,
controller_id)
return data
@NXActionController2Prop.register_type(nicira_ext.NXAC2PT_REASON)
class NXActionController2PropReason(NXActionController2Prop):
# reason
_fmt_str = "!B3x"
_arg_name = "reason"
@classmethod
def parser_prop(cls, buf, length):
size = 4
(reason,) = struct.unpack_from(
cls._fmt_str, buf, 0)
return reason, size
@classmethod
def serialize_prop(cls, reason):
data = bytearray()
msg_pack_into("!HHB3x", data, 0,
nicira_ext.NXAC2PT_REASON,
5,
reason)
return data
@NXActionController2Prop.register_type(nicira_ext.NXAC2PT_USERDATA)
class NXActionController2PropUserData(NXActionController2Prop):
# userdata
_fmt_str = "!B"
_arg_name = "userdata"
@classmethod
def parser_prop(cls, buf, length):
userdata = []
offset = 0
while offset < length:
u = struct.unpack_from(cls._fmt_str, buf, offset)
userdata.append(u[0])
offset += 1
user_size = utils.round_up(length, 4)
if user_size > 4 and (user_size % 8) == 0:
size = utils.round_up(length, 4) + 4
else:
size = utils.round_up(length, 4)
return userdata, size
@classmethod
def serialize_prop(cls, userdata):
data = bytearray()
user_buf = bytearray()
user_offset = 0
for user in userdata:
msg_pack_into('!B', user_buf, user_offset,
user)
user_offset += 1
msg_pack_into("!HH", data, 0,
nicira_ext.NXAC2PT_USERDATA,
4 + user_offset)
data += user_buf
if user_offset > 4:
user_len = utils.round_up(user_offset, 4)
brank_size = 0
if (user_len % 8) == 0:
brank_size = 4
msg_pack_into("!%dx" % (user_len - user_offset + brank_size),
data, 4 + user_offset)
else:
user_len = utils.round_up(user_offset, 4)
msg_pack_into("!%dx" % (user_len - user_offset),
data, 4 + user_offset)
return data
@NXActionController2Prop.register_type(nicira_ext.NXAC2PT_PAUSE)
class NXActionController2PropPause(NXActionController2Prop):
_arg_name = "pause"
@classmethod
def parser_prop(cls, buf, length):
pause = True
size = 4
return pause, size
@classmethod
def serialize_prop(cls, pause):
data = bytearray()
msg_pack_into("!HH4x", data, 0,
nicira_ext.NXAC2PT_PAUSE,
4)
return data
class NXActionDecTtlCntIds(NXAction):
r"""
Decrement TTL action
This action decrements TTL of IPv4 packet or
hop limits of IPv6 packet.
And equivalent to the followings action of ovs-ofctl command.
..
dec_ttl(id1[,id2]...)
..
+-------------------------------------------+
| **dec_ttl(**\ *id1*\[,\ *id2*\]...\ **)** |
+-------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
cnt_ids Controller ids
================ ======================================================
Example::
actions += [parser.NXActionDecTtlCntIds(cnt_ids=[1,2,3])]
.. NOTE::
If you want to set the following ovs-ofctl command.
Please use ``OFPActionDecNwTtl``.
+-------------+
| **dec_ttl** |
+-------------+
"""
_subtype = nicira_ext.NXAST_DEC_TTL_CNT_IDS
# controllers
_fmt_str = '!H4x'
_fmt_len = 6
def __init__(self,
cnt_ids,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionDecTtlCntIds, self).__init__()
self.cnt_ids = cnt_ids
@classmethod
def parser(cls, buf):
(controllers,) = struct.unpack_from(
cls._fmt_str, buf)
offset = cls._fmt_len
cnt_ids = []
for i in range(0, controllers):
id_ = struct.unpack_from('!H', buf, offset)
cnt_ids.append(id_[0])
offset += 2
return cls(cnt_ids)
def serialize_body(self):
assert isinstance(self.cnt_ids, (tuple, list))
for i in self.cnt_ids:
assert isinstance(i, six.integer_types)
controllers = len(self.cnt_ids)
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
controllers)
offset = self._fmt_len
for id_ in self.cnt_ids:
msg_pack_into('!H', data, offset, id_)
offset += 2
id_len = (utils.round_up(controllers, 4) -
controllers)
if id_len != 0:
msg_pack_into('%dx' % id_len * 2, data, offset)
return data
# Use in only OpenFlow1.0
class NXActionMplsBase(NXAction):
# ethertype
_fmt_str = '!H4x'
def __init__(self,
ethertype,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionMplsBase, self).__init__()
self.ethertype = ethertype
@classmethod
def parser(cls, buf):
(ethertype,) = struct.unpack_from(
cls._fmt_str, buf)
return cls(ethertype)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.ethertype)
return data
# For OpenFlow1.0 only
class NXActionPushMpls(NXActionMplsBase):
r"""
Push MPLS action
This action pushes a new MPLS header to the packet.
And equivalent to the followings action of ovs-ofctl command.
..
push_mpls:ethertype
..
+-------------------------------+
| **push_mpls**\:\ *ethertype* |
+-------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
ethertype Ether type(The value must be either 0x8847 or 0x8848)
================ ======================================================
.. NOTE::
This actions is supported by
``OFPActionPushMpls``
in OpenFlow1.2 or later.
Example::
match = parser.OFPMatch(dl_type=0x0800)
actions += [parser.NXActionPushMpls(ethertype=0x8847)]
"""
_subtype = nicira_ext.NXAST_PUSH_MPLS
# For OpenFlow1.0 only
class NXActionPopMpls(NXActionMplsBase):
r"""
Pop MPLS action
This action pops the MPLS header from the packet.
And equivalent to the followings action of ovs-ofctl command.
..
pop_mpls:ethertype
..
+------------------------------+
| **pop_mpls**\:\ *ethertype* |
+------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
ethertype Ether type
================ ======================================================
.. NOTE::
This actions is supported by
``OFPActionPopMpls``
in OpenFlow1.2 or later.
Example::
match = parser.OFPMatch(dl_type=0x8847)
actions += [parser.NXActionPushMpls(ethertype=0x0800)]
"""
_subtype = nicira_ext.NXAST_POP_MPLS
# For OpenFlow1.0 only
class NXActionSetMplsTtl(NXAction):
r"""
Set MPLS TTL action
This action sets the MPLS TTL.
And equivalent to the followings action of ovs-ofctl command.
..
set_mpls_ttl:ttl
..
+---------------------------+
| **set_mpls_ttl**\:\ *ttl* |
+---------------------------+
================ ======================================================
Attribute Description
================ ======================================================
ttl MPLS TTL
================ ======================================================
.. NOTE::
This actions is supported by
``OFPActionSetMplsTtl``
in OpenFlow1.2 or later.
Example::
actions += [parser.NXActionSetMplsTil(ttl=128)]
"""
_subtype = nicira_ext.NXAST_SET_MPLS_TTL
# ethertype
_fmt_str = '!B5x'
def __init__(self,
ttl,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionSetMplsTtl, self).__init__()
self.ttl = ttl
@classmethod
def parser(cls, buf):
(ttl,) = struct.unpack_from(
cls._fmt_str, buf)
return cls(ttl)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.ttl)
return data
# For OpenFlow1.0 only
class NXActionDecMplsTtl(NXAction):
"""
Decrement MPLS TTL action
This action decrements the MPLS TTL.
And equivalent to the followings action of ovs-ofctl command.
..
dec_mpls_ttl
..
+------------------+
| **dec_mpls_ttl** |
+------------------+
.. NOTE::
This actions is supported by
``OFPActionDecMplsTtl``
in OpenFlow1.2 or later.
Example::
actions += [parser.NXActionDecMplsTil()]
"""
_subtype = nicira_ext.NXAST_DEC_MPLS_TTL
# ethertype
_fmt_str = '!6x'
def __init__(self,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionDecMplsTtl, self).__init__()
@classmethod
def parser(cls, buf):
return cls()
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0)
return data
# For OpenFlow1.0 only
class NXActionSetMplsLabel(NXAction):
r"""
Set MPLS Lavel action
This action sets the MPLS Label.
And equivalent to the followings action of ovs-ofctl command.
..
set_mpls_label:label
..
+-------------------------------+
| **set_mpls_label**\:\ *label* |
+-------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
label MPLS Label
================ ======================================================
.. NOTE::
This actions is supported by
``OFPActionSetField(mpls_label=label)``
in OpenFlow1.2 or later.
Example::
actions += [parser.NXActionSetMplsLabel(label=0x10)]
"""
_subtype = nicira_ext.NXAST_SET_MPLS_LABEL
# ethertype
_fmt_str = '!2xI'
def __init__(self,
label,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionSetMplsLabel, self).__init__()
self.label = label
@classmethod
def parser(cls, buf):
(label,) = struct.unpack_from(
cls._fmt_str, buf)
return cls(label)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.label)
return data
# For OpenFlow1.0 only
class NXActionSetMplsTc(NXAction):
r"""
Set MPLS Tc action
This action sets the MPLS Tc.
And equivalent to the followings action of ovs-ofctl command.
..
set_mpls_tc:tc
..
+-------------------------+
| **set_mpls_tc**\:\ *tc* |
+-------------------------+
================ ======================================================
Attribute Description
================ ======================================================
tc MPLS Tc
================ ======================================================
.. NOTE::
This actions is supported by
``OFPActionSetField(mpls_label=tc)``
in OpenFlow1.2 or later.
Example::
actions += [parser.NXActionSetMplsLabel(tc=0x10)]
"""
_subtype = nicira_ext.NXAST_SET_MPLS_TC
# ethertype
_fmt_str = '!B5x'
def __init__(self,
tc,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionSetMplsTc, self).__init__()
self.tc = tc
@classmethod
def parser(cls, buf):
(tc,) = struct.unpack_from(
cls._fmt_str, buf)
return cls(tc)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.tc)
return data
class NXActionStackBase(NXAction):
# start, field, end
_fmt_str = '!H4sH'
_TYPE = {
'ascii': [
'field',
]
}
def __init__(self,
field,
start,
end,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionStackBase, self).__init__()
self.field = field
self.start = start
self.end = end
@classmethod
def parser(cls, buf):
(start, oxm_data, end) = struct.unpack_from(
cls._fmt_str, buf, 0)
(n, len_) = ofp.oxm_parse_header(oxm_data, 0)
field = ofp.oxm_to_user_header(n)
return cls(field, start, end)
def serialize_body(self):
data = bytearray()
oxm_data = bytearray()
oxm = ofp.oxm_from_user_header(self.field)
ofp.oxm_serialize_header(oxm, oxm_data, 0)
msg_pack_into(self._fmt_str, data, 0,
self.start,
six.binary_type(oxm_data),
self.end)
offset = len(data)
msg_pack_into("!%dx" % (12 - offset), data, offset)
return data
class NXActionStackPush(NXActionStackBase):
r"""
Push field action
This action pushes field to top of the stack.
And equivalent to the followings action of ovs-ofctl command.
..
pop:dst[start...end]
..
+----------------------------------------------------+
| **pop**\:\ *dst*\ **[**\ *start*\...\ *end*\ **]** |
+----------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
field OXM/NXM header for source field
start Start bit for source field
end End bit for source field
================ ======================================================
Example::
actions += [parser.NXActionStackPush(field="reg2",
start=0,
end=5)]
"""
_subtype = nicira_ext.NXAST_STACK_PUSH
class NXActionStackPop(NXActionStackBase):
r"""
Pop field action
This action pops field from top of the stack.
And equivalent to the followings action of ovs-ofctl command.
..
pop:src[start...end]
..
+----------------------------------------------------+
| **pop**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
+----------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
field OXM/NXM header for destination field
start Start bit for destination field
end End bit for destination field
================ ======================================================
Example::
actions += [parser.NXActionStackPop(field="reg2",
start=0,
end=5)]
"""
_subtype = nicira_ext.NXAST_STACK_POP
class NXActionSample(NXAction):
r"""
Sample packets action
This action samples packets and sends one sample for
every sampled packet.
And equivalent to the followings action of ovs-ofctl command.
..
sample(argument[,argument]...)
..
+----------------------------------------------------+
| **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
+----------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
probability The number of sampled packets
collector_set_id The unsigned 32-bit integer identifier of
the set of sample collectors to send sampled packets
to
obs_domain_id The Unsigned 32-bit integer Observation Domain ID
obs_point_id The unsigned 32-bit integer Observation Point ID
================ ======================================================
Example::
actions += [parser.NXActionSample(probability=3,
collector_set_id=1,
obs_domain_id=2,
obs_point_id=3,)]
"""
_subtype = nicira_ext.NXAST_SAMPLE
# probability, collector_set_id, obs_domain_id, obs_point_id
_fmt_str = '!HIII'
def __init__(self,
probability,
collector_set_id=0,
obs_domain_id=0,
obs_point_id=0,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionSample, self).__init__()
self.probability = probability
self.collector_set_id = collector_set_id
self.obs_domain_id = obs_domain_id
self.obs_point_id = obs_point_id
@classmethod
def parser(cls, buf):
(probability,
collector_set_id,
obs_domain_id,
obs_point_id) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(probability,
collector_set_id,
obs_domain_id,
obs_point_id)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.probability,
self.collector_set_id,
self.obs_domain_id,
self.obs_point_id)
return data
class NXActionSample2(NXAction):
r"""
Sample packets action
This action samples packets and sends one sample for
every sampled packet.
'sampling_port' can be equal to ingress port or one of egress ports.
And equivalent to the followings action of ovs-ofctl command.
..
sample(argument[,argument]...)
..
+----------------------------------------------------+
| **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
+----------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
probability The number of sampled packets
collector_set_id The unsigned 32-bit integer identifier of
the set of sample collectors to send sampled packets to
obs_domain_id The Unsigned 32-bit integer Observation Domain ID
obs_point_id The unsigned 32-bit integer Observation Point ID
sampling_port Sampling port number
================ ======================================================
Example::
actions += [parser.NXActionSample2(probability=3,
collector_set_id=1,
obs_domain_id=2,
obs_point_id=3,
sampling_port=8080)]
"""
_subtype = nicira_ext.NXAST_SAMPLE2
# probability, collector_set_id, obs_domain_id,
# obs_point_id, sampling_port
_fmt_str = '!HIIIH6x'
def __init__(self,
probability,
collector_set_id=0,
obs_domain_id=0,
obs_point_id=0,
sampling_port=0,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionSample2, self).__init__()
self.probability = probability
self.collector_set_id = collector_set_id
self.obs_domain_id = obs_domain_id
self.obs_point_id = obs_point_id
self.sampling_port = sampling_port
@classmethod
def parser(cls, buf):
(probability,
collector_set_id,
obs_domain_id,
obs_point_id,
sampling_port) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(probability,
collector_set_id,
obs_domain_id,
obs_point_id,
sampling_port)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.probability,
self.collector_set_id,
self.obs_domain_id,
self.obs_point_id,
self.sampling_port)
return data
class NXActionFinTimeout(NXAction):
r"""
Change TCP timeout action
This action changes the idle timeout or hard timeout or
both, of this OpenFlow rule when the rule matches a TCP
packet with the FIN or RST flag.
And equivalent to the followings action of ovs-ofctl command.
..
fin_timeout(argument[,argument]...)
..
+---------------------------------------------------------+
| **fin_timeout(**\ *argument*\[,\ *argument*\]...\ **)** |
+---------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
fin_idle_timeout Causes the flow to expire after the given number
of seconds of inactivity
fin_idle_timeout Causes the flow to expire after the given number
of second, regardless of activity
================ ======================================================
Example::
match = parser.OFPMatch(ip_proto=6, eth_type=0x0800)
actions += [parser.NXActionFinTimeout(fin_idle_timeout=30,
fin_hard_timeout=60)]
"""
_subtype = nicira_ext.NXAST_FIN_TIMEOUT
# fin_idle_timeout, fin_hard_timeout
_fmt_str = '!HH2x'
def __init__(self,
fin_idle_timeout,
fin_hard_timeout,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionFinTimeout, self).__init__()
self.fin_idle_timeout = fin_idle_timeout
self.fin_hard_timeout = fin_hard_timeout
@classmethod
def parser(cls, buf):
(fin_idle_timeout,
fin_hard_timeout) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(fin_idle_timeout,
fin_hard_timeout)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.fin_idle_timeout,
self.fin_hard_timeout)
return data
class NXActionConjunction(NXAction):
r"""
Conjunctive matches action
This action ties groups of individual OpenFlow flows into
higher-level conjunctive flows.
Please refer to the ovs-ofctl command manual for details.
And equivalent to the followings action of ovs-ofctl command.
..
conjunction(id,k/n)
..
+--------------------------------------------------+
| **conjunction(**\ *id*\,\ *k*\ **/**\ *n*\ **)** |
+--------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
clause Number assigned to the flow's dimension
n_clauses Specify the conjunctive flow's match condition
id\_ Conjunction ID
================ ======================================================
Example::
actions += [parser.NXActionConjunction(clause=1,
n_clauses=2,
id_=10)]
"""
_subtype = nicira_ext.NXAST_CONJUNCTION
# clause, n_clauses, id
_fmt_str = '!BBI'
def __init__(self,
clause,
n_clauses,
id_,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionConjunction, self).__init__()
self.clause = clause
self.n_clauses = n_clauses
self.id = id_
@classmethod
def parser(cls, buf):
(clause,
n_clauses,
id_,) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(clause, n_clauses, id_)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.clause,
self.n_clauses,
self.id)
return data
class NXActionMultipath(NXAction):
r"""
Select multipath link action
This action selects multipath link based on the specified parameters.
Please refer to the ovs-ofctl command manual for details.
And equivalent to the followings action of ovs-ofctl command.
..
multipath(fields, basis, algorithm, n_links, arg, dst[start..end])
..
+-------------------------------------------------------------+
| **multipath(**\ *fields*\, \ *basis*\, \ *algorithm*\, |
| *n_links*\, \ *arg*\, \ *dst*\[\ *start*\..\ *end*\]\ **)** |
+-------------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
fields One of NX_HASH_FIELDS_*
basis Universal hash parameter
algorithm One of NX_MP_ALG_*.
max_link Number of output links
arg Algorithm-specific argument
ofs_nbits Start and End for the OXM/NXM field.
Setting method refer to the ``nicira_ext.ofs_nbits``
dst OXM/NXM header for source field
================ ======================================================
Example::
actions += [parser.NXActionMultipath(
fields=nicira_ext.NX_HASH_FIELDS_SYMMETRIC_L4,
basis=1024,
algorithm=nicira_ext.NX_MP_ALG_HRW,
max_link=5,
arg=0,
ofs_nbits=nicira_ext.ofs_nbits(4, 31),
dst="reg2")]
"""
_subtype = nicira_ext.NXAST_MULTIPATH
# fields, basis, algorithm, max_link,
# arg, ofs_nbits, dst
_fmt_str = '!HH2xHHI2xH4s'
_TYPE = {
'ascii': [
'dst',
]
}
def __init__(self,
fields,
basis,
algorithm,
max_link,
arg,
ofs_nbits,
dst,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionMultipath, self).__init__()
self.fields = fields
self.basis = basis
self.algorithm = algorithm
self.max_link = max_link
self.arg = arg
self.ofs_nbits = ofs_nbits
self.dst = dst
@classmethod
def parser(cls, buf):
(fields,
basis,
algorithm,
max_link,
arg,
ofs_nbits,
oxm_data) = struct.unpack_from(
cls._fmt_str, buf, 0)
(n, len_) = ofp.oxm_parse_header(oxm_data, 0)
dst = ofp.oxm_to_user_header(n)
return cls(fields,
basis,
algorithm,
max_link,
arg,
ofs_nbits,
dst)
def serialize_body(self):
data = bytearray()
dst = bytearray()
oxm = ofp.oxm_from_user_header(self.dst)
ofp.oxm_serialize_header(oxm, dst, 0),
msg_pack_into(self._fmt_str, data, 0,
self.fields,
self.basis,
self.algorithm,
self.max_link,
self.arg,
self.ofs_nbits,
six.binary_type(dst))
return data
class _NXActionBundleBase(NXAction):
# algorithm, fields, basis, slave_type, n_slaves
# ofs_nbits
_fmt_str = '!HHHIHH'
def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
ofs_nbits, dst, slaves):
super(_NXActionBundleBase, self).__init__()
self.len = utils.round_up(
nicira_ext.NX_ACTION_BUNDLE_0_SIZE + len(slaves) * 2, 8)
self.algorithm = algorithm
self.fields = fields
self.basis = basis
self.slave_type = slave_type
self.n_slaves = n_slaves
self.ofs_nbits = ofs_nbits
self.dst = dst
assert isinstance(slaves, (list, tuple))
for s in slaves:
assert isinstance(s, six.integer_types)
self.slaves = slaves
@classmethod
def parser(cls, buf):
# Add dst ('I') to _fmt_str
(algorithm, fields, basis,
slave_type, n_slaves, ofs_nbits, dst) = struct.unpack_from(
cls._fmt_str + 'I', buf, 0)
offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
if dst != 0:
(n, len_) = ofp.oxm_parse_header(buf, offset)
dst = ofp.oxm_to_user_header(n)
slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
nicira_ext.NX_ACTION_HEADER_0_SIZE)
slaves = []
for i in range(0, n_slaves):
s = struct.unpack_from('!H', buf, slave_offset)
slaves.append(s[0])
slave_offset += 2
return cls(algorithm, fields, basis, slave_type,
n_slaves, ofs_nbits, dst, slaves)
def serialize_body(self):
data = bytearray()
slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
nicira_ext.NX_ACTION_HEADER_0_SIZE)
self.n_slaves = len(self.slaves)
for s in self.slaves:
msg_pack_into('!H', data, slave_offset, s)
slave_offset += 2
pad_len = (utils.round_up(self.n_slaves, 4) -
self.n_slaves)
if pad_len != 0:
msg_pack_into('%dx' % pad_len * 2, data, slave_offset)
msg_pack_into(self._fmt_str, data, 0,
self.algorithm, self.fields, self.basis,
self.slave_type, self.n_slaves,
self.ofs_nbits)
offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
if self.dst == 0:
msg_pack_into('I', data, offset, self.dst)
else:
oxm_data = ofp.oxm_from_user_header(self.dst)
ofp.oxm_serialize_header(oxm_data, data, offset)
return data
class NXActionBundle(_NXActionBundleBase):
r"""
Select bundle link action
This action selects bundle link based on the specified parameters.
Please refer to the ovs-ofctl command manual for details.
And equivalent to the followings action of ovs-ofctl command.
..
bundle(fields, basis, algorithm, slave_type, slaves:[ s1, s2,...])
..
+-----------------------------------------------------------+
| **bundle(**\ *fields*\, \ *basis*\, \ *algorithm*\, |
| *slave_type*\, \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** |
+-----------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
algorithm One of NX_MP_ALG_*.
fields One of NX_HASH_FIELDS_*
basis Universal hash parameter
slave_type Type of slaves(must be NXM_OF_IN_PORT)
n_slaves Number of slaves
ofs_nbits Start and End for the OXM/NXM field. (must be zero)
dst OXM/NXM header for source field(must be zero)
slaves List of slaves
================ ======================================================
Example::
actions += [parser.NXActionBundle(
algorithm=nicira_ext.NX_MP_ALG_HRW,
fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
basis=0,
slave_type=nicira_ext.NXM_OF_IN_PORT,
n_slaves=2,
ofs_nbits=0,
dst=0,
slaves=[2, 3])]
"""
_subtype = nicira_ext.NXAST_BUNDLE
def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
ofs_nbits, dst, slaves):
# NXAST_BUNDLE actions should have 'sofs_nbits' and 'dst' zeroed.
super(NXActionBundle, self).__init__(
algorithm, fields, basis, slave_type, n_slaves,
ofs_nbits=0, dst=0, slaves=slaves)
class NXActionBundleLoad(_NXActionBundleBase):
r"""
Select bundle link action
This action has the same behavior as the bundle action,
with one exception.
Please refer to the ovs-ofctl command manual for details.
And equivalent to the followings action of ovs-ofctl command.
..
bundle_load(fields, basis, algorithm, slave_type,
dst[start..end], slaves:[ s1, s2,...])
..
+-----------------------------------------------------------+
| **bundle_load(**\ *fields*\, \ *basis*\, \ *algorithm*\, |
| *slave_type*\, \ *dst*\[\ *start*\... \*emd*\], |
| \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** | |
+-----------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
algorithm One of NX_MP_ALG_*.
fields One of NX_HASH_FIELDS_*
basis Universal hash parameter
slave_type Type of slaves(must be NXM_OF_IN_PORT)
n_slaves Number of slaves
ofs_nbits Start and End for the OXM/NXM field.
Setting method refer to the ``nicira_ext.ofs_nbits``
dst OXM/NXM header for source field
slaves List of slaves
================ ======================================================
Example::
actions += [parser.NXActionBundleLoad(
algorithm=nicira_ext.NX_MP_ALG_HRW,
fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
basis=0,
slave_type=nicira_ext.NXM_OF_IN_PORT,
n_slaves=2,
ofs_nbits=nicira_ext.ofs_nbits(4, 31),
dst="reg0",
slaves=[2, 3])]
"""
_subtype = nicira_ext.NXAST_BUNDLE_LOAD
_TYPE = {
'ascii': [
'dst',
]
}
def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
ofs_nbits, dst, slaves):
super(NXActionBundleLoad, self).__init__(
algorithm, fields, basis, slave_type, n_slaves,
ofs_nbits, dst, slaves)
class NXActionCT(NXAction):
r"""
Pass traffic to the connection tracker action
This action sends the packet through the connection tracker.
And equivalent to the followings action of ovs-ofctl command.
..
ct(argument[,argument]...)
..
+------------------------------------------------+
| **ct(**\ *argument*\[,\ *argument*\]...\ **)** |
+------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
flags Zero or more(Unspecified flag bits must be zero.)
zone_src OXM/NXM header for source field
zone_ofs_nbits Start and End for the OXM/NXM field.
Setting method refer to the ``nicira_ext.ofs_nbits``.
If you need set the Immediate value for zone,
zone_src must be set to None or empty character string.
recirc_table Recirculate to a specific table
alg Well-known port number for the protocol
actions Zero or more actions may immediately follow this
action
================ ======================================================
.. NOTE::
If you set number to zone_src,
Traceback occurs when you run the to_jsondict.
Example::
match = parser.OFPMatch(eth_type=0x0800, ct_state=(0,32))
actions += [parser.NXActionCT(
flags = 1,
zone_src = "reg0",
zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
recirc_table = 4,
alg = 0,
actions = [])]
"""
_subtype = nicira_ext.NXAST_CT
# flags, zone_src, zone_ofs_nbits, recirc_table,
# pad, alg
_fmt_str = '!H4sHB3xH'
_TYPE = {
'ascii': [
'zone_src',
]
}
# Followed by actions
def __init__(self,
flags,
zone_src,
zone_ofs_nbits,
recirc_table,
alg,
actions,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionCT, self).__init__()
self.flags = flags
self.zone_src = zone_src
self.zone_ofs_nbits = zone_ofs_nbits
self.recirc_table = recirc_table
self.alg = alg
self.actions = actions
@classmethod
def parser(cls, buf):
(flags,
oxm_data,
zone_ofs_nbits,
recirc_table,
alg,) = struct.unpack_from(
cls._fmt_str, buf, 0)
rest = buf[struct.calcsize(cls._fmt_str):]
# OXM/NXM field
if oxm_data == b'\x00' * 4:
zone_src = ""
else:
(n, len_) = ofp.oxm_parse_header(oxm_data, 0)
zone_src = ofp.oxm_to_user_header(n)
# actions
actions = []
while len(rest) > 0:
action = ofpp.OFPAction.parser(rest, 0)
actions.append(action)
rest = rest[action.len:]
return cls(flags, zone_src, zone_ofs_nbits, recirc_table,
alg, actions)
def serialize_body(self):
data = bytearray()
# If zone_src is zero, zone_ofs_nbits is zone_imm
if not self.zone_src:
zone_src = b'\x00' * 4
elif isinstance(self.zone_src, six.integer_types):
zone_src = struct.pack("!I", self.zone_src)
else:
zone_src = bytearray()
oxm = ofp.oxm_from_user_header(self.zone_src)
ofp.oxm_serialize_header(oxm, zone_src, 0)
msg_pack_into(self._fmt_str, data, 0,
self.flags,
six.binary_type(zone_src),
self.zone_ofs_nbits,
self.recirc_table,
self.alg)
for a in self.actions:
a.serialize(data, len(data))
return data
class NXActionCTClear(NXAction):
"""
Clear connection tracking state action
This action clears connection tracking state from packets.
And equivalent to the followings action of ovs-ofctl command.
..
ct_clear
..
+--------------+
| **ct_clear** |
+--------------+
Example::
actions += [parser.NXActionCTClear()]
"""
_subtype = nicira_ext.NXAST_CT_CLEAR
_fmt_str = '!6x'
def __init__(self,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionCTClear, self).__init__()
@classmethod
def parser(cls, buf):
return cls()
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0)
return data
class NXActionNAT(NXAction):
r"""
Network address translation action
This action sends the packet through the connection tracker.
And equivalent to the followings action of ovs-ofctl command.
.. NOTE::
The following command image does not exist in ovs-ofctl command
manual and has been created from the command response.
..
nat(src=ip_min-ip_max : proto_min-proto-max)
..
+--------------------------------------------------+
| **nat(src**\=\ *ip_min*\ **-**\ *ip_max*\ **:** |
| *proto_min*\ **-**\ *proto-max*\ **)** |
+--------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
flags Zero or more(Unspecified flag bits must be zero.)
range_ipv4_min Range ipv4 address minimun
range_ipv4_max Range ipv4 address maximun
range_ipv6_min Range ipv6 address minimun
range_ipv6_max Range ipv6 address maximun
range_proto_min Range protocol minimum
range_proto_max Range protocol maximun
================ ======================================================
.. CAUTION::
``NXActionNAT`` must be defined in the actions in the
``NXActionCT``.
Example::
match = parser.OFPMatch(eth_type=0x0800)
actions += [
parser.NXActionCT(
flags = 1,
zone_src = "reg0",
zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
recirc_table = 255,
alg = 0,
actions = [
parser.NXActionNAT(
flags = 1,
range_ipv4_min = "10.1.12.0",
range_ipv4_max = "10.1.13.255",
range_ipv6_min = "",
range_ipv6_max = "",
range_proto_min = 1,
range_proto_max = 1023
)
]
)
]
"""
_subtype = nicira_ext.NXAST_NAT
# pad, flags, range_present
_fmt_str = '!2xHH'
# Followed by optional parameters
_TYPE = {
'ascii': [
'range_ipv4_max',
'range_ipv4_min',
'range_ipv6_max',
'range_ipv6_min',
]
}
def __init__(self,
flags,
range_ipv4_min='',
range_ipv4_max='',
range_ipv6_min='',
range_ipv6_max='',
range_proto_min=None,
range_proto_max=None,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionNAT, self).__init__()
self.flags = flags
self.range_ipv4_min = range_ipv4_min
self.range_ipv4_max = range_ipv4_max
self.range_ipv6_min = range_ipv6_min
self.range_ipv6_max = range_ipv6_max
self.range_proto_min = range_proto_min
self.range_proto_max = range_proto_max
@classmethod
def parser(cls, buf):
(flags,
range_present) = struct.unpack_from(
cls._fmt_str, buf, 0)
rest = buf[struct.calcsize(cls._fmt_str):]
# optional parameters
kwargs = dict()
if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MIN:
kwargs['range_ipv4_min'] = type_desc.IPv4Addr.to_user(rest[:4])
rest = rest[4:]
if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MAX:
kwargs['range_ipv4_max'] = type_desc.IPv4Addr.to_user(rest[:4])
rest = rest[4:]
if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MIN:
kwargs['range_ipv6_min'] = (
type_desc.IPv6Addr.to_user(rest[:16]))
rest = rest[16:]
if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MAX:
kwargs['range_ipv6_max'] = (
type_desc.IPv6Addr.to_user(rest[:16]))
rest = rest[16:]
if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MIN:
kwargs['range_proto_min'] = type_desc.Int2.to_user(rest[:2])
rest = rest[2:]
if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MAX:
kwargs['range_proto_max'] = type_desc.Int2.to_user(rest[:2])
return cls(flags, **kwargs)
def serialize_body(self):
# Pack optional parameters first, as range_present needs
# to be calculated.
optional_data = b''
range_present = 0
if self.range_ipv4_min != '':
range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MIN
optional_data += type_desc.IPv4Addr.from_user(
self.range_ipv4_min)
if self.range_ipv4_max != '':
range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MAX
optional_data += type_desc.IPv4Addr.from_user(
self.range_ipv4_max)
if self.range_ipv6_min != '':
range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MIN
optional_data += type_desc.IPv6Addr.from_user(
self.range_ipv6_min)
if self.range_ipv6_max != '':
range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MAX
optional_data += type_desc.IPv6Addr.from_user(
self.range_ipv6_max)
if self.range_proto_min is not None:
range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MIN
optional_data += type_desc.Int2.from_user(
self.range_proto_min)
if self.range_proto_max is not None:
range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MAX
optional_data += type_desc.Int2.from_user(
self.range_proto_max)
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.flags,
range_present)
msg_pack_into('!%ds' % len(optional_data), data, len(data),
optional_data)
return data
class NXActionOutputTrunc(NXAction):
r"""
Truncate output action
This action truncate a packet into the specified size and outputs it.
And equivalent to the followings action of ovs-ofctl command.
..
output(port=port,max_len=max_len)
..
+--------------------------------------------------------------+
| **output(port**\=\ *port*\,\ **max_len**\=\ *max_len*\ **)** |
+--------------------------------------------------------------+
================ ======================================================
Attribute Description
================ ======================================================
port Output port
max_len Max bytes to send
================ ======================================================
Example::
actions += [parser.NXActionOutputTrunc(port=8080,
max_len=1024)]
"""
_subtype = nicira_ext.NXAST_OUTPUT_TRUNC
# port, max_len
_fmt_str = '!HI'
def __init__(self,
port,
max_len,
type_=None, len_=None, experimenter=None, subtype=None):
super(NXActionOutputTrunc, self).__init__()
self.port = port
self.max_len = max_len
@classmethod
def parser(cls, buf):
(port,
max_len) = struct.unpack_from(
cls._fmt_str, buf, 0)
return cls(port, max_len)
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0,
self.port,
self.max_len)
return data
class NXActionDecNshTtl(NXAction):
"""
Decrement NSH TTL action
This action decrements the TTL in the Network Service Header(NSH).
This action was added in OVS v2.9.
And equivalent to the followings action of ovs-ofctl command.
::
dec_nsh_ttl
Example::
actions += [parser.NXActionDecNshTtl()]
"""
_subtype = nicira_ext.NXAST_DEC_NSH_TTL
_fmt_str = '!6x'
def __init__(self,
type_=None, len_=None, vendor=None, subtype=None):
super(NXActionDecNshTtl, self).__init__()
@classmethod
def parser(cls, buf):
return cls()
def serialize_body(self):
data = bytearray()
msg_pack_into(self._fmt_str, data, 0)
return data
def add_attr(k, v):
v.__module__ = ofpp.__name__ # Necessary for stringify stuff
setattr(ofpp, k, v)
add_attr('NXAction', NXAction)
add_attr('NXActionUnknown', NXActionUnknown)
classes = [
'NXActionSetQueue',
'NXActionPopQueue',
'NXActionRegLoad',
'NXActionRegLoad2',
'NXActionNote',
'NXActionSetTunnel',
'NXActionSetTunnel64',
'NXActionRegMove',
'NXActionResubmit',
'NXActionResubmitTable',
'NXActionOutputReg',
'NXActionOutputReg2',
'NXActionLearn',
'NXActionExit',
'NXActionDecTtl',
'NXActionController',
'NXActionController2',
'NXActionDecTtlCntIds',
'NXActionPushMpls',
'NXActionPopMpls',
'NXActionSetMplsTtl',
'NXActionDecMplsTtl',
'NXActionSetMplsLabel',
'NXActionSetMplsTc',
'NXActionStackPush',
'NXActionStackPop',
'NXActionSample',
'NXActionSample2',
'NXActionFinTimeout',
'NXActionConjunction',
'NXActionMultipath',
'NXActionBundle',
'NXActionBundleLoad',
'NXActionCT',
'NXActionCTClear',
'NXActionNAT',
'NXActionOutputTrunc',
'_NXFlowSpec', # exported for testing
'NXFlowSpecMatch',
'NXFlowSpecLoad',
'NXFlowSpecOutput',
'NXActionDecNshTtl',
]
vars = locals()
for name in classes:
cls = vars[name]
add_attr(name, cls)
if issubclass(cls, NXAction):
NXAction.register(cls)
if issubclass(cls, _NXFlowSpec):
_NXFlowSpec.register(cls)