Hi Iwamoto-San
> You meant commit 3c3896fd77f274ce953dcb78795aa5cc4fde6c65? Sorry it was my mistake. Modify commit ID to 3c3896fd77f274ce953dcb78795aa5cc4fde6c65. > I think it's better to separate this into the pure revert patch and > the other changes in order to make git history more readable. Separate this into the revert patch and the other changes. However, revert patch has an impact on the document. Therefore, document fixes and method additions include in revert patch. > Sorry for the crappy API, but I think we need a nice warning at least > if we change jsondict outputs of NXActionCT.parser. Write the following as caution. If the value of zone_src is other than zero, there is case that value of the zone_src is set by the parser as a string. Thanks, On 2016年07月20日 16:19, IWAMOTO Toshihiro wrote: > At Wed, 20 Jul 2016 13:36:41 +0900, > Shinpei Muraoka wrote: >> >> This patch will revert the API of NXAction for the following report. >> https://bugs.launchpad.net/dragonflow/+bug/1599367 >> revert commit id: a01f8f0aa03cd85df25555fc07e7217c2a79e7f0 > > You meant commit 3c3896fd77f274ce953dcb78795aa5cc4fde6c65? > > I think it's better to separate this into the pure revert patch and > the other changes in order to make git history more readable. > >> Add the utility method for ofs_nbits. >> >> Since the zone_src in NXActionCT was not possible to specify string, >> update zone_src of NXActionCT for the uniformity. >> Therefore,you will be able to specify string of OXM/NXM fields for zone_src. > > Sorry for the crappy API, but I think we need a nice warning at least > if we change jsondict outputs of NXActionCT.parser. > >> Additionally, update test cases and documents. >> >> Signed-off-by: Shinpei Muraoka <shinpei.mura...@gmail.com> >> --- >> doc/source/nicira_ext_ref.rst | 1 + >> ryu/ofproto/nicira_ext.py | 33 +++ >> ryu/ofproto/nx_actions.py | 253 >> ++++++++++----------- >> .../of13/ovs-ofctl-of13-action_ct.packet | Bin 104 -> 104 bytes >> ryu/tests/packet_data_generator3/gen.py | 2 +- >> .../json/of13/ovs-ofctl-of13-action_ct.packet.json | 5 +- >> .../of13/ovs-ofctl-of13-action_ct_exec.packet.json | 3 +- >> .../of13/ovs-ofctl-of13-action_ct_nat.packet.json | 3 +- >> .../ovs-ofctl-of13-action_ct_nat_v6.packet.json | 3 +- >> ...s-ofctl-of13-match_load_nx_register.packet.json | 5 +- >> ...s-ofctl-of13-match_move_nx_register.packet.json | 7 +- >> ryu/tests/unit/ofproto/test_parser_v10.py | 76 ++----- >> 12 files changed, 188 insertions(+), 203 deletions(-) >> >> diff --git a/doc/source/nicira_ext_ref.rst b/doc/source/nicira_ext_ref.rst >> index 1385079..739349c 100644 >> --- a/doc/source/nicira_ext_ref.rst >> +++ b/doc/source/nicira_ext_ref.rst >> @@ -57,6 +57,7 @@ The followings shows the supported NXAction classes in >> OpenFlow1.0 or later >> .. autoclass:: NXFlowSpecMatch >> .. autoclass:: NXFlowSpecLoad >> .. autoclass:: NXFlowSpecOutput >> +.. autofunction:: ryu.ofproto.nicira_ext.ofs_nbits >> >> .. _nx_match_structures: >> >> diff --git a/ryu/ofproto/nicira_ext.py b/ryu/ofproto/nicira_ext.py >> index 57c62c6..e2fca47 100644 >> --- a/ryu/ofproto/nicira_ext.py >> +++ b/ryu/ofproto/nicira_ext.py >> @@ -278,6 +278,39 @@ NX_NAT_RANGE_PROTO_MIN = 1 << 4 >> NX_NAT_RANGE_PROTO_MAX = 1 << 5 >> >> >> +def ofs_nbits(start, end): >> + """ >> + The utility method for ofs_nbits >> + >> + This method is used in the class to set the ofs_nbits. >> + >> + This method converts start/end bits into ofs_nbits required to >> + specify the bit range of OXM/NXM fields. >> + >> + ofs_nbits can be calculated as following:: >> + >> + ofs_nbits = (start << 6) + (end - start) >> + >> + The parameter start/end means the OXM/NXM field of ovs-ofctl command. >> + >> + .. >> + field[start..end] >> + .. >> + >> + +------------------------------------------+ >> + | *field*\ **[**\ *start*\..\ *end*\ **]** | >> + +------------------------------------------+ >> + >> + ================ ====================================================== >> + Attribute Description >> + ================ ====================================================== >> + start Start bit for OXM/NXM field >> + end End bit for OXM/NXM field >> + ================ ====================================================== >> + """ >> + return (start << 6) + (end - start) >> + >> + >> def nxm_header__(vendor, field, hasmask, length): >> return (vendor << 16) | (field << 9) | (hasmask << 8) | length >> >> diff --git a/ryu/ofproto/nx_actions.py b/ryu/ofproto/nx_actions.py >> index 94c2213..6bd9b55 100644 >> --- a/ryu/ofproto/nx_actions.py >> +++ b/ryu/ofproto/nx_actions.py >> @@ -15,6 +15,7 @@ >> # limitations under the License. >> >> import six >> +import base64 >> >> import struct >> >> @@ -356,18 +357,18 @@ def generate(ofp_name, ofpp_name): >> ================ >> ====================================================== >> Attribute Description >> ================ >> ====================================================== >> - start Start bit for destination field >> - end End bit for destination field >> + 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(start=4, >> - end=31, >> - dst="eth_dst", >> - value=0x112233)] >> + 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 >> @@ -377,11 +378,10 @@ def generate(ofp_name, ofpp_name): >> ] >> } >> >> - def __init__(self, start, end, dst, value, >> + def __init__(self, ofs_nbits, dst, value, > > For some reason, it was ofs and nbits for NXActionRegLoad. > Please retain the old API. > >> type_=None, len_=None, experimenter=None, >> subtype=None): >> super(NXActionRegLoad, self).__init__() >> - self.start = start >> - self.end = end >> + self.ofs_nbits = ofs_nbits >> self.dst = dst >> self.value = value >> >> @@ -389,11 +389,9 @@ def generate(ofp_name, ofpp_name): >> def parser(cls, buf): >> (ofs_nbits, dst, value,) = struct.unpack_from( >> cls._fmt_str, buf, 0) >> - start = ofs_nbits >> 6 >> - end = (ofs_nbits & 0x3f) + start >> # Right-shift instead of using oxm_parse_header for >> simplicity... >> dst_name = ofp.oxm_to_user_header(dst >> 9) >> - return cls(start, end, dst_name, value) >> + return cls(ofs_nbits, dst_name, value) >> >> def serialize_body(self): >> hdr_data = bytearray() >> @@ -401,10 +399,9 @@ def generate(ofp_name, ofpp_name): >> ofp.oxm_serialize_header(n, hdr_data, 0) >> (dst_num,) = struct.unpack_from('!I', >> six.binary_type(hdr_data), 0) >> >> - ofs_nbits = (self.start << 6) + (self.end - self.start) >> data = bytearray() >> msg_pack_into(self._fmt_str, data, 0, >> - ofs_nbits, dst_num, self.value) >> + self.ofs_nbits, dst_num, self.value) >> return data >> >> class NXActionRegLoad2(NXAction): >> @@ -671,11 +668,10 @@ def generate(ofp_name, ofpp_name): >> Attribute Description >> ================ >> ====================================================== >> src_field OXM/NXM header for source field >> - src_start Start bit for source field >> - src_end End bit for source field >> dst_field OXM/NXM header for destination field >> - dst_start Start bit for destination field >> - dst_end End bit for destination field >> + n_bits Number of bits >> + src_ofs Starting bit offset in source >> + dst_ofs Starting bit offset in destination >> ================ >> ====================================================== >> >> .. CAUTION:: >> @@ -685,11 +681,10 @@ def generate(ofp_name, ofpp_name): >> Example:: >> >> actions += [parser.NXActionRegMove(src_field="reg0", >> - src_start=0, >> - src_end=5, >> dst_field="reg1", >> - dst_start=10, >> - dst_end=15)] >> + n_bits=5, >> + src_ofs=0 >> + dst_ofs=10)] >> """ >> _subtype = nicira_ext.NXAST_REG_MOVE >> _fmt_str = '!HHH' # n_bits, src_ofs, dst_ofs >> @@ -701,16 +696,14 @@ def generate(ofp_name, ofpp_name): >> ] >> } >> >> - def __init__(self, src_field, src_start, src_end, >> - dst_field, dst_start, dst_end, >> + 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.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): >> @@ -718,11 +711,6 @@ def generate(ofp_name, ofpp_name): >> 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) >> @@ -732,17 +720,14 @@ def generate(ofp_name, ofpp_name): >> dst_field = ofp.oxm_to_user_header(n) >> rest = rest[len:] >> # ignore padding >> - return cls(src_field, src_start, src_end, >> - dst_field, dst_start, dst_end) >> + 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() >> - 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, >> - n_bits, self.src_start, self.dst_start) >> + 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)) >> @@ -874,18 +859,18 @@ def generate(ofp_name, ofpp_name): >> ================ >> ====================================================== >> Attribute Description >> ================ >> ====================================================== >> - start Start bit for source field >> - end End bit for source field >> + 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(start=8080, >> - end=10, >> - src="reg0", >> - max_len=1024)] >> + actions += [parser.NXActionOutputReg( >> + ofs_nbits=nicira_ext.ofs_nbits(4, 31), >> + src="reg0", >> + max_len=1024)] >> """ >> _subtype = nicira_ext.NXAST_OUTPUT_REG >> >> @@ -898,14 +883,12 @@ def generate(ofp_name, ofpp_name): >> } >> >> def __init__(self, >> - start, >> - end, >> + ofs_nbits, >> src, >> max_len, >> type_=None, len_=None, experimenter=None, >> subtype=None): >> super(NXActionOutputReg, self).__init__() >> - self.start = start >> - self.end = end >> + self.ofs_nbits = ofs_nbits >> self.src = src >> self.max_len = max_len >> >> @@ -913,23 +896,19 @@ def generate(ofp_name, ofpp_name): >> def parser(cls, buf): >> (ofs_nbits, oxm_data, max_len) = 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, >> + return cls(ofs_nbits, >> src, >> max_len) >> >> def serialize_body(self): >> data = bytearray() >> src = bytearray() >> - ofs_nbits = (self.start << 6) + (self.end - self.start) >> oxm = ofp.oxm_from_user_header(self.src) >> ofp.oxm_serialize_header(oxm, src, 0), >> msg_pack_into(self._fmt_str, data, 0, >> - ofs_nbits, >> + self.ofs_nbits, >> six.binary_type(src), >> self.max_len) >> return data >> @@ -958,22 +937,22 @@ def generate(ofp_name, ofpp_name): >> ================ >> ====================================================== >> Attribute Description >> ================ >> ====================================================== >> - start Start bit for source field >> - end End bit for source field >> + 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(start=8080, >> - end=10, >> - src="reg0", >> - max_len=1024)] >> + actions += [parser.NXActionOutputReg2( >> + ofs_nbits=nicira_ext.ofs_nbits(4, 31), >> + src="reg0", >> + max_len=1024)] >> """ >> _subtype = nicira_ext.NXAST_OUTPUT_REG2 >> >> - # start, end, src, max_len >> + # ofs_nbits, src, max_len >> _fmt_str = '!HH4s' >> _TYPE = { >> 'ascii': [ >> @@ -982,14 +961,12 @@ def generate(ofp_name, ofpp_name): >> } >> >> def __init__(self, >> - start, >> - end, >> + ofs_nbits, >> src, >> max_len, >> type_=None, len_=None, experimenter=None, >> subtype=None): >> super(NXActionOutputReg2, self).__init__() >> - self.start = start >> - self.end = end >> + self.ofs_nbits = ofs_nbits >> self.src = src >> self.max_len = max_len >> >> @@ -999,23 +976,19 @@ def generate(ofp_name, ofpp_name): >> 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, >> + return cls(ofs_nbits, >> 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.ofs_nbits, >> self.max_len, >> six.binary_type(oxm_data)) >> offset = len(data) >> @@ -2394,8 +2367,8 @@ def generate(ofp_name, ofpp_name): >> algorithm One of NX_MP_ALG_*. >> max_link Number of output links >> arg Algorithm-specific argument >> - start Start bit for source field >> - end End bit for source field >> + 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 >> ================ >> ====================================================== >> >> @@ -2407,8 +2380,7 @@ def generate(ofp_name, ofpp_name): >> algorithm=nicira_ext.NX_MP_ALG_HRW, >> max_link=5, >> arg=0, >> - start=4, >> - end=31, >> + ofs_nbits=nicira_ext.ofs_nbits(4, 31), >> dst="reg2")] >> """ >> _subtype = nicira_ext.NXAST_MULTIPATH >> @@ -2428,8 +2400,7 @@ def generate(ofp_name, ofpp_name): >> algorithm, >> max_link, >> arg, >> - start, >> - end, >> + ofs_nbits, >> dst, >> type_=None, len_=None, experimenter=None, >> subtype=None): >> super(NXActionMultipath, self).__init__() >> @@ -2438,8 +2409,7 @@ def generate(ofp_name, ofpp_name): >> self.algorithm = algorithm >> self.max_link = max_link >> self.arg = arg >> - self.start = start >> - self.end = end >> + self.ofs_nbits = ofs_nbits >> self.dst = dst >> >> @classmethod >> @@ -2452,8 +2422,6 @@ def generate(ofp_name, ofpp_name): >> ofs_nbits, >> 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) >> dst = ofp.oxm_to_user_header(n) >> return cls(fields, >> @@ -2461,14 +2429,12 @@ def generate(ofp_name, ofpp_name): >> algorithm, >> max_link, >> arg, >> - start, >> - end, >> + ofs_nbits, >> dst) >> >> def serialize_body(self): >> data = bytearray() >> dst = bytearray() >> - ofs_nbits = (self.start << 6) + (self.end - self.start) >> oxm = ofp.oxm_from_user_header(self.dst) >> ofp.oxm_serialize_header(oxm, dst, 0), >> msg_pack_into(self._fmt_str, data, 0, >> @@ -2477,7 +2443,7 @@ def generate(ofp_name, ofpp_name): >> self.algorithm, >> self.max_link, >> self.arg, >> - ofs_nbits, >> + self.ofs_nbits, >> six.binary_type(dst)) >> >> return data >> @@ -2488,7 +2454,7 @@ def generate(ofp_name, ofpp_name): >> _fmt_str = '!HHHIHH' >> >> def __init__(self, algorithm, fields, basis, slave_type, n_slaves, >> - start, end, dst, 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) >> @@ -2498,8 +2464,7 @@ def generate(ofp_name, ofpp_name): >> self.basis = basis >> self.slave_type = slave_type >> self.n_slaves = n_slaves >> - self.start = start >> - self.end = end >> + self.ofs_nbits = ofs_nbits >> self.dst = dst >> >> assert isinstance(slaves, (list, tuple)) >> @@ -2514,8 +2479,6 @@ def generate(ofp_name, ofpp_name): >> (algorithm, fields, basis, >> slave_type, n_slaves, ofs_nbits, dst) = struct.unpack_from( >> cls._fmt_str + 'I', buf, 0) >> - start = ofs_nbits >> 6 >> - end = (ofs_nbits & 0x3f) + start >> >> offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE - >> nicira_ext.NX_ACTION_HEADER_0_SIZE - 8) >> @@ -2534,10 +2497,9 @@ def generate(ofp_name, ofpp_name): >> slave_offset += 2 >> >> return cls(algorithm, fields, basis, slave_type, >> - n_slaves, start, end, dst, slaves) >> + n_slaves, ofs_nbits, dst, slaves) >> >> def serialize_body(self): >> - ofs_nbits = (self.start << 6) + (self.end - self.start) >> data = bytearray() >> slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE - >> nicira_ext.NX_ACTION_HEADER_0_SIZE) >> @@ -2554,7 +2516,7 @@ def generate(ofp_name, ofpp_name): >> msg_pack_into(self._fmt_str, data, 0, >> self.algorithm, self.fields, self.basis, >> self.slave_type, self.n_slaves, >> - ofs_nbits) >> + self.ofs_nbits) >> offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE - >> nicira_ext.NX_ACTION_HEADER_0_SIZE - 8) >> >> @@ -2591,8 +2553,7 @@ def generate(ofp_name, ofpp_name): >> basis Universal hash parameter >> slave_type Type of slaves(must be NXM_OF_IN_PORT) >> n_slaves Number of slaves >> - start Start bit for source field(must be zero) >> - end End bit for source field(must be zero) >> + 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 >> ================ >> ====================================================== >> @@ -2606,19 +2567,18 @@ def generate(ofp_name, ofpp_name): >> basis=0, >> slave_type=nicira_ext.NXM_OF_IN_PORT, >> n_slaves=2, >> - start=0, >> - end=0, >> + ofs_nbits=0, >> dst=0, >> slaves=[2, 3])] >> """ >> _subtype = nicira_ext.NXAST_BUNDLE >> >> def __init__(self, algorithm, fields, basis, slave_type, n_slaves, >> - start, end, dst, slaves): >> - # NXAST_BUNDLE actions should have 'start' 'end' and 'dst' >> zeroed. >> + 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, >> - start=0, end=0, dst=0, slaves=slaves) >> + ofs_nbits=0, dst=0, slaves=slaves) >> >> class NXActionBundleLoad(_NXActionBundleBase): >> """ >> @@ -2632,12 +2592,13 @@ def generate(ofp_name, ofpp_name): >> >> .. >> bundle_load(fields, basis, algorithm, slave_type, >> - slaves:[ s1, s2,...]) >> + dst[start..end], slaves:[ s1, s2,...]) >> .. >> >> +-----------------------------------------------------------+ >> | **bundle_load(**\ *fields*\, \ *basis*\, \ *algorithm*\, | >> - | *slave_type*\, \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** | >> + | *slave_type*\, \ *dst*\[\ *start*\... \*emd*\], | >> + | \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** | | >> +-----------------------------------------------------------+ >> >> ================ >> ====================================================== >> @@ -2648,8 +2609,8 @@ def generate(ofp_name, ofpp_name): >> basis Universal hash parameter >> slave_type Type of slaves(must be NXM_OF_IN_PORT) >> n_slaves Number of slaves >> - start Start bit for source field >> - end End bit for source field >> + 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 >> ================ >> ====================================================== >> @@ -2663,8 +2624,7 @@ def generate(ofp_name, ofpp_name): >> basis=0, >> slave_type=nicira_ext.NXM_OF_IN_PORT, >> n_slaves=2, >> - start=4, >> - end=31, >> + ofs_nbits=nicira_ext.ofs_nbits(4, 31), >> dst="reg0", >> slaves=[2, 3])] >> """ >> @@ -2676,10 +2636,10 @@ def generate(ofp_name, ofpp_name): >> } >> >> def __init__(self, algorithm, fields, basis, slave_type, n_slaves, >> - start, end, dst, slaves): >> + ofs_nbits, dst, slaves): >> super(NXActionBundleLoad, self).__init__( >> algorithm, fields, basis, slave_type, n_slaves, >> - start, end, dst, slaves) >> + ofs_nbits, dst, slaves) >> >> class NXActionCT(NXAction): >> """ >> @@ -2702,8 +2662,10 @@ def generate(ofp_name, ofpp_name): >> ================ >> ====================================================== >> flags Zero or more(Unspecified flag bits must be zero.) >> zone_src OXM/NXM header for source field >> - zone_start Start bit for source field >> - zone_end End bit 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 zero. >> recirc_table Recirculate to a specific table >> alg Well-known port number for the protocol >> actions Zero or more actions may immediately follow this >> @@ -2713,26 +2675,27 @@ def generate(ofp_name, ofpp_name): >> Example:: >> >> match = parser.OFPMatch(eth_type=0x0800, ct_state=(0,32)) >> - actions += [parser.NXActionCT(flags = 1, >> - zone_src = 0, >> - zone_start = 0, >> - zone_end = 0, >> - recirc_table = 4, >> - alg = 0, >> - actions = [])] >> + 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 = '!HIHB3xH' >> + _fmt_str = '!H4sHB3xH' >> + _TYPE = {'ascii': []} # appended before to_jsondict() >> + >> # Followed by actions >> >> def __init__(self, >> flags, >> zone_src, >> - zone_start, >> - zone_end, >> + zone_ofs_nbits, >> recirc_table, >> alg, >> actions, >> @@ -2740,8 +2703,7 @@ def generate(ofp_name, ofpp_name): >> super(NXActionCT, self).__init__() >> self.flags = flags >> self.zone_src = zone_src >> - self.zone_start = zone_start >> - self.zone_end = zone_end >> + self.zone_ofs_nbits = zone_ofs_nbits >> self.recirc_table = recirc_table >> self.alg = alg >> self.actions = actions >> @@ -2749,14 +2711,20 @@ def generate(ofp_name, ofpp_name): >> @classmethod >> def parser(cls, buf): >> (flags, >> - zone_src, >> + oxm_data, >> zone_ofs_nbits, >> recirc_table, >> alg,) = struct.unpack_from( >> cls._fmt_str, buf, 0) >> - zone_start = zone_ofs_nbits >> 6 >> - zone_end = (zone_ofs_nbits & 0x3f) + zone_start >> rest = buf[struct.calcsize(cls._fmt_str):] >> + >> + # OXM/NXM field >> + if oxm_data == b'\x00' * 4: >> + zone_src = 0 >> + else: >> + (n, len_) = ofp.oxm_parse_header(oxm_data, 0) >> + zone_src = ofp.oxm_to_user_header(n) >> + >> # actions >> actions = [] >> while len(rest) > 0: >> @@ -2764,23 +2732,41 @@ def generate(ofp_name, ofpp_name): >> actions.append(action) >> rest = rest[action.len:] >> >> - return cls(flags, zone_src, zone_start, zone_end, recirc_table, >> + return cls(flags, zone_src, zone_ofs_nbits, recirc_table, >> alg, actions) >> >> def serialize_body(self): >> - zone_ofs_nbits = ((self.zone_start << 6) + >> - (self.zone_end - self.zone_start)) >> data = bytearray() >> + # If zone_src is zero, zone_ofs_nbits is zone_imm >> + if self.zone_src == 0: >> + zone_src = b'\x00' * 4 >> + # For backward compatibility >> + 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, >> - self.zone_src, >> - zone_ofs_nbits, >> + 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 >> >> + def to_jsondict(self, encode_string=base64.b64encode): >> + if (isinstance(self.zone_src, (str, six.text_type)) and >> + 'zone_src' not in self._TYPE['ascii']): >> + self._TYPE['ascii'].append('zone_src') >> + elif (isinstance(self.zone_src, six.integer_types) and >> + 'zone_src' in self._TYPE['ascii']): >> + self._TYPE['ascii'].remove('zone_src') >> + return super(NXActionCT, self).to_jsondict(encode_string) >> + >> class NXActionNAT(NXAction): >> """ >> Network address translation action >> @@ -2824,9 +2810,8 @@ def generate(ofp_name, ofpp_name): >> actions += [ >> parser.NXActionCT( >> flags = 1, >> - zone_src = 0, >> - zone_start = 0, >> - zone_end = 0, >> + zone_src = "reg0", >> + zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31), >> recirc_table = 255, >> alg = 0, >> actions = [ >> diff --git a/ryu/tests/packet_data/of13/ovs-ofctl-of13-action_ct.packet >> b/ryu/tests/packet_data/of13/ovs-ofctl-of13-action_ct.packet >> index >> 3aff2bdc3e516a200a34604ce6236b10b247cd03..5eb733f969fbabe7d5d88ec279422b3d5fd286d0 >> 100644 >> GIT binary patch >> delta 16 >> Ucmd1Em=Md&$iTuV&B6cz02<K&?f?J) >> >> delta 16 >> Rcmd1Em=Md&00Jyv5&#+90nGpa >> >> diff --git a/ryu/tests/packet_data_generator3/gen.py >> b/ryu/tests/packet_data_generator3/gen.py >> index 65f91a7..92676e4 100644 >> --- a/ryu/tests/packet_data_generator3/gen.py >> +++ b/ryu/tests/packet_data_generator3/gen.py >> @@ -108,7 +108,7 @@ MESSAGES = [ >> 'args': (['table=3,', >> 'importance=39032'] + >> ['dl_type=0x0800,ct_state=-trk'] + >> - ['actions=ct(table=4)'])}, >> + ['actions=ct(table=4,zone=NXM_NX_REG0[4..31])'])}, >> {'name': 'action_ct_exec', >> 'versions': [4], >> 'cmd': 'add-flow', >> diff --git >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct.packet.json >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct.packet.json >> index 473b54f..b1157e9 100644 >> --- a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct.packet.json >> +++ b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct.packet.json >> @@ -21,9 +21,8 @@ >> "recirc_table": 4, >> "subtype": 35, >> "type": 65535, >> - "zone_start": 0, >> - "zone_end": 0, >> - "zone_src": 0 >> + "zone_ofs_nbits": 283, >> + "zone_src": "reg0" >> } >> } >> ], >> diff --git >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_exec.packet.json >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_exec.packet.json >> index 7cecad7..a163aba 100644 >> --- >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_exec.packet.json >> +++ >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_exec.packet.json >> @@ -35,8 +35,7 @@ >> "recirc_table": 255, >> "subtype": 35, >> "type": 65535, >> - "zone_start": 0, >> - "zone_end": 0, >> + "zone_ofs_nbits": 0, >> "zone_src": 0 >> } >> } >> diff --git >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat.packet.json >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat.packet.json >> index b63c226..ef6a7d9 100644 >> --- >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat.packet.json >> +++ >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat.packet.json >> @@ -37,8 +37,7 @@ >> "recirc_table": 255, >> "subtype": 35, >> "type": 65535, >> - "zone_start": 0, >> - "zone_end": 0, >> + "zone_ofs_nbits": 0, >> "zone_src": 0 >> } >> } >> diff --git >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat_v6.packet.json >> >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat_v6.packet.json >> index e50d561..cca4625 100644 >> --- >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat_v6.packet.json >> +++ >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat_v6.packet.json >> @@ -37,8 +37,7 @@ >> "recirc_table": 255, >> "subtype": 35, >> "type": 65535, >> - "zone_start": 0, >> - "zone_end": 0, >> + "zone_ofs_nbits": 0, >> "zone_src": 0 >> } >> } >> diff --git >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_load_nx_register.packet.json >> >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_load_nx_register.packet.json >> index 05ced1e..c60851a 100644 >> --- >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_load_nx_register.packet.json >> +++ >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_load_nx_register.packet.json >> @@ -16,8 +16,7 @@ >> "dst": "reg0", >> "experimenter": 8992, >> "len": 24, >> - "end": 31, >> - "start": 4, >> + "ofs_nbits": 283, >> "subtype": 7, >> "type": 65535, >> "value": 233495534 >> @@ -26,7 +25,7 @@ >> ], >> "len": 32, >> "type": 4 >> - } >> + } >> } >> ], >> "match": { >> diff --git >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_move_nx_register.packet.json >> >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_move_nx_register.packet.json >> index d31294e..7457278 100644 >> --- >> a/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_move_nx_register.packet.json >> +++ >> b/ryu/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_move_nx_register.packet.json >> @@ -13,14 +13,13 @@ >> "actions": [ >> { >> "NXActionRegMove": { >> - "dst_end": 5, >> "dst_field": "reg1", >> - "dst_start": 0, >> + "dst_ofs": 0, >> "experimenter": 8992, >> "len": 24, >> - "src_end": 15, >> + "n_bits": 6, >> "src_field": "reg0", >> - "src_start": 10, >> + "src_ofs": 10, >> "subtype": 6, >> "type": 65535 >> } >> diff --git a/ryu/tests/unit/ofproto/test_parser_v10.py >> b/ryu/tests/unit/ofproto/test_parser_v10.py >> index 55edc77..eefb65f 100644 >> --- a/ryu/tests/unit/ofproto/test_parser_v10.py >> +++ b/ryu/tests/unit/ofproto/test_parser_v10.py >> @@ -1391,10 +1391,6 @@ class TestNXActionRegMove(unittest.TestCase): >> dst_ofs = {'buf': b'\xdc\x67', 'val': 56423} >> src_field = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", "val2": 65540} >> dst_field = {'buf': b'\x00\x01\x02\x04', 'val': "reg1", "val2": 66052} >> - src_start = 62371 >> - src_end = 78138 >> - dst_start = 56423 >> - dst_end = 72190 >> >> buf = type_['buf'] \ >> + len_['buf'] \ >> @@ -1407,11 +1403,10 @@ class TestNXActionRegMove(unittest.TestCase): >> + dst_field['buf'] >> >> c = NXActionRegMove(src_field['val'], >> - src_start, >> - src_end, >> dst_field['val'], >> - dst_start, >> - dst_end) >> + n_bits['val'], >> + src_ofs['val'], >> + dst_ofs['val']) >> >> def setUp(self): >> pass >> @@ -1422,23 +1417,21 @@ class TestNXActionRegMove(unittest.TestCase): >> def test_init(self): >> eq_(self.subtype['val'], self.c.subtype) >> eq_(self.src_field['val'], self.c.src_field) >> - eq_(self.src_start, self.c.src_start) >> - eq_(self.src_end, self.c.src_end) >> eq_(self.dst_field['val'], self.c.dst_field) >> - eq_(self.dst_start, self.c.dst_start) >> - eq_(self.dst_end, self.c.dst_end) >> + eq_(self.n_bits['val'], self.c.n_bits) >> + eq_(self.src_field['val'], self.c.src_field) >> + eq_(self.dst_field['val'], self.c.dst_field) >> >> def test_parser(self): >> res = OFPActionVendor.parser(self.buf, 0) >> eq_(self.type_['val'], res.type) >> eq_(self.len_['val'], res.len) >> eq_(self.subtype['val'], res.subtype) >> + eq_(self.src_ofs['val'], res.src_ofs) >> + eq_(self.dst_ofs['val'], res.dst_ofs) >> + eq_(self.n_bits['val'], res.n_bits) >> eq_(self.src_field['val'], res.src_field) >> - eq_(self.src_start, res.src_start) >> - eq_(self.src_end, res.src_end) >> eq_(self.dst_field['val'], res.dst_field) >> - eq_(self.dst_start, res.dst_start) >> - eq_(self.dst_end, res.dst_end) >> >> def test_serialize(self): >> buf = bytearray() >> @@ -1485,8 +1478,7 @@ class TestNXActionRegLoad(unittest.TestCase): >> + dst['buf'] \ >> + value['buf'] >> >> - c = NXActionRegLoad(start, >> - end, >> + c = NXActionRegLoad(ofs_nbits['val'], >> dst['val'], >> value['val']) >> >> @@ -1498,8 +1490,7 @@ class TestNXActionRegLoad(unittest.TestCase): >> >> def test_init(self): >> eq_(self.subtype['val'], self.c.subtype) >> - eq_(self.start, self.c.start) >> - eq_(self.end, self.c.end) >> + eq_(self.ofs_nbits['val'], self.c.ofs_nbits) >> eq_(self.dst['val'], self.c.dst) >> eq_(self.value['val'], self.c.value) >> >> @@ -1507,8 +1498,7 @@ class TestNXActionRegLoad(unittest.TestCase): >> res = OFPActionVendor.parser(self.buf, 0) >> eq_(self.type_['val'], res.type) >> eq_(self.len_['val'], res.len) >> - eq_(self.start, self.c.start) >> - eq_(self.end, self.c.end) >> + eq_(self.ofs_nbits['val'], self.c.ofs_nbits) >> eq_(self.dst['val'], res.dst) >> eq_(self.value['val'], res.value) >> >> @@ -1626,8 +1616,7 @@ class TestNXActionMultipath(unittest.TestCase): >> algorithm['val'], >> max_link['val'], >> arg['val'], >> - start, >> - end, >> + ofs_nbits['val'], >> dst['val']) >> >> def setUp(self): >> @@ -1643,8 +1632,7 @@ class TestNXActionMultipath(unittest.TestCase): >> eq_(self.algorithm['val'], self.c.algorithm) >> eq_(self.max_link['val'], self.c.max_link) >> eq_(self.arg['val'], self.c.arg) >> - eq_(self.start, self.c.start) >> - eq_(self.end, self.c.end) >> + eq_(self.ofs_nbits['val'], self.c.ofs_nbits) >> eq_(self.dst['val'], self.c.dst) >> >> def test_parser(self): >> @@ -1657,8 +1645,7 @@ class TestNXActionMultipath(unittest.TestCase): >> eq_(self.algorithm['val'], res.algorithm) >> eq_(self.max_link['val'], res.max_link) >> eq_(self.arg['val'], res.arg) >> - eq_(self.start, res.start) >> - eq_(self.end, res.end) >> + eq_(self.ofs_nbits['val'], res.ofs_nbits) >> eq_(self.dst['val'], res.dst) >> >> def test_serialize(self): >> @@ -1705,8 +1692,6 @@ class TestNXActionBundle(unittest.TestCase): >> >> slaves_buf = (b'\x00\x01', b'\x00\x02') >> slaves_val = (1, 2) >> - start = 0 >> - end = 0 >> >> _len = len_['val'] + len(slaves_val) * 2 >> _len += (_len % 8) >> @@ -1731,8 +1716,7 @@ class TestNXActionBundle(unittest.TestCase): >> basis['val'], >> slave_type['val'], >> n_slaves['val'], >> - start, >> - end, >> + ofs_nbits['val'], >> dst['val'], >> slaves_val) >> >> @@ -1749,8 +1733,7 @@ class TestNXActionBundle(unittest.TestCase): >> eq_(self.basis['val'], self.c.basis) >> eq_(self.slave_type['val'], self.c.slave_type) >> eq_(self.n_slaves['val'], self.c.n_slaves) >> - eq_(self.start, self.c.start) >> - eq_(self.end, self.c.end) >> + eq_(self.ofs_nbits['val'], self.c.ofs_nbits) >> eq_(self.dst['val'], self.c.dst) >> >> # slaves >> @@ -1768,8 +1751,7 @@ class TestNXActionBundle(unittest.TestCase): >> eq_(self.basis['val'], res.basis) >> eq_(self.slave_type['val'], res.slave_type) >> eq_(self.n_slaves['val'], res.n_slaves) >> - eq_(self.start, res.start) >> - eq_(self.end, res.end) >> + eq_(self.ofs_nbits['val'], res.ofs_nbits) >> eq_(self.dst['val'], res.dst) >> >> # slaves >> @@ -1821,8 +1803,6 @@ class TestNXActionBundleLoad(unittest.TestCase): >> ofs_nbits = {'buf': b'\xd2\x9d', 'val': 53917} >> dst = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", 'val2': 65540} >> zfill = b'\x00' * 4 >> - start = 842 >> - end = 871 >> >> slaves_buf = (b'\x00\x01', b'\x00\x02') >> slaves_val = (1, 2) >> @@ -1850,8 +1830,7 @@ class TestNXActionBundleLoad(unittest.TestCase): >> basis['val'], >> slave_type['val'], >> n_slaves['val'], >> - start, >> - end, >> + ofs_nbits['val'], >> dst['val'], >> slaves_val) >> >> @@ -1868,8 +1847,7 @@ class TestNXActionBundleLoad(unittest.TestCase): >> eq_(self.basis['val'], self.c.basis) >> eq_(self.slave_type['val'], self.c.slave_type) >> eq_(self.n_slaves['val'], self.c.n_slaves) >> - eq_(self.start, self.c.start) >> - eq_(self.end, self.c.end) >> + eq_(self.ofs_nbits['val'], self.c.ofs_nbits) >> eq_(self.dst['val'], self.c.dst) >> >> # slaves >> @@ -1887,8 +1865,7 @@ class TestNXActionBundleLoad(unittest.TestCase): >> eq_(self.basis['val'], res.basis) >> eq_(self.slave_type['val'], res.slave_type) >> eq_(self.n_slaves['val'], res.n_slaves) >> - eq_(self.start, res.start) >> - eq_(self.end, res.end) >> + eq_(self.ofs_nbits['val'], res.ofs_nbits) >> eq_(self.dst['val'], res.dst) >> >> # slaves >> @@ -1935,8 +1912,6 @@ class TestNXActionOutputReg(unittest.TestCase): >> src = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", 'val2': 65540} >> max_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} >> zfill = b'\x00' * 6 >> - start = 1017 >> - end = 1073 >> >> buf = type_['buf'] \ >> + len_['buf'] \ >> @@ -1947,8 +1922,7 @@ class TestNXActionOutputReg(unittest.TestCase): >> + max_len['buf'] \ >> + zfill >> >> - c = NXActionOutputReg(start, >> - end, >> + c = NXActionOutputReg(ofs_nbits['val'], >> src['val'], >> max_len['val']) >> >> @@ -1960,8 +1934,7 @@ class TestNXActionOutputReg(unittest.TestCase): >> >> def test_init(self): >> eq_(self.subtype['val'], self.c.subtype) >> - eq_(self.start, self.c.start) >> - eq_(self.end, self.c.end) >> + eq_(self.ofs_nbits['val'], self.c.ofs_nbits) >> eq_(self.src['val'], self.c.src) >> eq_(self.max_len['val'], self.c.max_len) >> >> @@ -1970,8 +1943,7 @@ class TestNXActionOutputReg(unittest.TestCase): >> eq_(self.type_['val'], res.type) >> eq_(self.len_['val'], res.len) >> eq_(self.subtype['val'], res.subtype) >> - eq_(self.start, self.c.start) >> - eq_(self.end, self.c.end) >> + eq_(self.ofs_nbits['val'], self.c.ofs_nbits) >> eq_(self.src['val'], res.src) >> eq_(self.max_len['val'], res.max_len) >> >> -- >> 1.9.1 >> >> >> ------------------------------------------------------------------------------ >> What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic >> patterns at an interface-level. Reveals which users, apps, and protocols are >> consuming the most bandwidth. Provides multi-vendor support for NetFlow, >> J-Flow, sFlow and other flows. Make informed decisions using capacity >> planning >> reports.http://sdm.link/zohodev2dev >> _______________________________________________ >> Ryu-devel mailing list >> Ryu-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/ryu-devel >> ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports.http://sdm.link/zohodev2dev _______________________________________________ Ryu-devel mailing list Ryu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ryu-devel