Actions to be added are as following.
 - NXActionDecTtlCntIds
 - NXActionStackPush
 - NXActionStackPop
 - NXActionSample
 - NXActionOutputReg2
 - NXActionRegLoad2
 - NXActionController2

Signed-off-by: Shinpei Muraoka <[email protected]>
---
 ryu/ofproto/nicira_ext.py |  14 ++
 ryu/ofproto/nx_actions.py | 474 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 480 insertions(+), 8 deletions(-)

diff --git a/ryu/ofproto/nicira_ext.py b/ryu/ofproto/nicira_ext.py
index c5af140..5306b59 100644
--- a/ryu/ofproto/nicira_ext.py
+++ b/ryu/ofproto/nicira_ext.py
@@ -44,15 +44,22 @@ NXAST_EXIT = 17
 NXAST_DEC_TTL = 18
 NXAST_FIN_TIMEOUT = 19
 NXAST_CONTROLLER = 20
+NXAST_DEC_TTL_CNT_IDS = 21
 NXAST_PUSH_MPLS = 23
 NXAST_POP_MPLS = 24
 NXAST_SET_MPLS_TTL = 25
 NXAST_DEC_MPLS_TTL = 26
+NXAST_STACK_PUSH = 27
+NXAST_STACK_POP = 28
+NXAST_SAMPLE = 29
 NXAST_SET_MPLS_LABEL = 30
 NXAST_SET_MPLS_TC = 31
+NXAST_OUTPUT_REG2 = 32
+NXAST_REG_LOAD2 = 33
 NXAST_CONJUNCTION = 34
 NXAST_CT = 35
 NXAST_NAT = 36
+NXAST_CONTROLLER2 = 37
 
 NX_ACTION_RESUBMIT_PACK_STR = '!HHIHHB3x'
 NX_ACTION_RESUBMIT_SIZE = 16
@@ -151,6 +158,13 @@ NXST_FLOW = 0
 NXST_AGGREGATE = 1
 NXST_FLOW_MONITOR = 2
 
+# enum nx_action_controller2_prop_type
+NXAC2PT_MAX_LEN = 0
+NXAC2PT_CONTROLLER_ID = 1
+NXAC2PT_REASON = 2
+NXAC2PT_USERDATA = 3
+NXAC2PT_PAUSE = 4
+
 NICIRA_HEADER_PACK_STR = '!II'
 NICIRA_HEADER_SIZE = 16
 assert (calcsize(NICIRA_HEADER_PACK_STR) +
diff --git a/ryu/ofproto/nx_actions.py b/ryu/ofproto/nx_actions.py
index 4cd1894..74ca14a 100644
--- a/ryu/ofproto/nx_actions.py
+++ b/ryu/ofproto/nx_actions.py
@@ -280,6 +280,46 @@ def generate(ofp_name, ofpp_name):
                           ofs_nbits, dst_num, self.value)
             return data
 
+    class NXActionRegLoad2(NXAction):
+        _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):
         _subtype = nicira_ext.NXAST_NOTE
 
@@ -357,20 +397,28 @@ def generate(ofp_name, ofpp_name):
             ]
         }
 
-        def __init__(self, src_field, dst_field, n_bits, src_ofs=0, dst_ofs=0,
+        def __init__(self, src_field, src_start, src_end,
+                     dst_field, dst_start, dst_end,
                      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.src_start = src_start
+            self.src_end = src_end
             self.dst_field = dst_field
+            self.dst_start = dst_start
+            self.dst_end = dst_end
 
         @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_start = src_ofs
+            src_end = src_ofs + n_bits - 1
+            dst_start = dst_ofs
+            dst_end = dst_ofs + n_bits - 1
+
             # src field
             (n, len) = ofp.oxm_parse_header(rest, 0)
             src_field = ofp.oxm_to_user_header(n)
@@ -380,14 +428,17 @@ def generate(ofp_name, ofpp_name):
             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)
+            return cls(src_field, src_start, src_end,
+                       dst_field, dst_start, dst_end)
 
         def serialize_body(self):
             # fixup
             data = bytearray()
+            n_bits = self.src_end - self.src_start + 1
+            assert n_bits == self.dst_end - self.dst_start + 1
+
             msg_pack_into(self._fmt_str, data, 0,
-                          self.n_bits, self.src_ofs, self.dst_ofs)
+                          n_bits, self.src_start, self.dst_start)
             # src field
             n = ofp.oxm_from_user_header(self.src_field)
             ofp.oxm_serialize_header(n, data, len(data))
@@ -495,6 +546,58 @@ def generate(ofp_name, ofpp_name):
                           self.max_len)
             return data
 
+    class NXActionOutputReg2(NXAction):
+        _subtype = nicira_ext.NXAST_OUTPUT_REG2
+
+        # start, end, src, max_len
+        _fmt_str = '!HH4s'
+        _TYPE = {
+            'ascii': [
+                'src',
+            ]
+        }
+
+        def __init__(self,
+                     start,
+                     end,
+                     src,
+                     max_len,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionOutputReg2, self).__init__()
+            self.start = start
+            self.end = end
+            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)
+            start = ofs_nbits >> 6
+            end = (ofs_nbits & 0x3f) + start
+            (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
+            src = ofp.oxm_to_user_header(n)
+            return cls(start,
+                       end,
+                       src,
+                       max_len)
+
+        def serialize_body(self):
+            data = bytearray()
+            oxm_data = bytearray()
+            ofs_nbits = (self.start << 6) + (self.end - self.start)
+            oxm = ofp.oxm_from_user_header(self.src)
+            ofp.oxm_serialize_header(oxm, oxm_data, 0),
+            msg_pack_into(self._fmt_str, data, 0,
+                          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):
         _subtype = nicira_ext.NXAST_LEARN
 
@@ -641,7 +744,270 @@ def generate(ofp_name, ofpp_name):
                           self.reason)
             return data
 
-    # For OpenFlow1.0 only
+    class NXActionController2(NXAction):
+        _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):
+        _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'
@@ -767,6 +1133,91 @@ def generate(ofp_name, ofpp_name):
                           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):
+        _subtype = nicira_ext.NXAST_STACK_PUSH
+
+    class NXActionStackPop(NXActionStackBase):
+        _subtype = nicira_ext.NXAST_STACK_POP
+
+    class NXActionSample(NXAction):
+        _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 NXActionFinTimeout(NXAction):
         _subtype = nicira_ext.NXAST_FIN_TIMEOUT
 
@@ -1182,6 +1633,7 @@ def generate(ofp_name, ofpp_name):
         'NXActionSetQueue',
         'NXActionPopQueue',
         'NXActionRegLoad',
+        'NXActionRegLoad2',
         'NXActionNote',
         'NXActionSetTunnel',
         'NXActionSetTunnel64',
@@ -1189,16 +1641,22 @@ def generate(ofp_name, ofpp_name):
         'NXActionResubmit',
         'NXActionResubmitTable',
         'NXActionOutputReg',
+        'NXActionOutputReg2',
         'NXActionLearn',
         'NXActionExit',
         'NXActionDecTtl',
         'NXActionController',
+        'NXActionController2',
+        'NXActionDecTtlCntIds',
         'NXActionPushMpls',
         'NXActionPopMpls',
         'NXActionSetMplsTtl',
         'NXActionDecMplsTtl',
         'NXActionSetMplsLabel',
         'NXActionSetMplsTc',
+        'NXActionStackPush',
+        'NXActionStackPop',
+        'NXActionSample',
         'NXActionFinTimeout',
         'NXActionConjunction',
         'NXActionMultipath',
-- 
1.9.1


------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to