Signed-off-by: Simon Horman <[email protected]>
---
 ryu/ofproto/ofproto_v1_4_parser.py | 123 +++++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/ryu/ofproto/ofproto_v1_4_parser.py 
b/ryu/ofproto/ofproto_v1_4_parser.py
index facfab3..770816d 100644
--- a/ryu/ofproto/ofproto_v1_4_parser.py
+++ b/ryu/ofproto/ofproto_v1_4_parser.py
@@ -2322,3 +2322,126 @@ class OFPActionSetQueue(OFPAction):
     def serialize(self, buf, offset):
         msg_pack_into(ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf,
                       offset, self.type, self.len, self.queue_id)
+
+
[email protected]_action_type(ofproto.OFPAT_SET_FIELD,
+                                ofproto.OFP_ACTION_SET_FIELD_SIZE)
+class OFPActionSetField(OFPAction):
+    """
+    Set field action
+
+    This action modifies a header field in the packet.
+
+    ================ ======================================================
+    Attribute        Description
+    ================ ======================================================
+    field            Instance of ``OFPMatchField``
+    ================ ======================================================
+    """
+    def __init__(self, field=None, **kwargs):
+        # old api
+        #   OFPActionSetField(field)
+        # new api
+        #   OFPActionSetField(eth_src="00:00:00:00:00")
+        super(OFPActionSetField, self).__init__()
+        if isinstance(field, OFPMatchField):
+            # old api compat
+            assert len(kwargs) == 0
+            self.field = field
+        else:
+            # new api
+            assert len(kwargs) == 1
+            key = kwargs.keys()[0]
+            value = kwargs[key]
+            assert isinstance(key, (str, unicode))
+            assert not isinstance(value, tuple)  # no mask
+            self.key = key
+            self.value = value
+
+    @classmethod
+    def parser(cls, buf, offset):
+        (type_, len_) = struct.unpack_from(
+            ofproto.OFP_ACTION_SET_FIELD_PACK_STR, buf, offset)
+        (n, value, mask, _len) = ofproto.oxm_parse(buf, offset + 4)
+        k, uv = ofproto.oxm_to_user(n, value, mask)
+        action = cls(**{k: uv})
+        action.len = len_
+
+        # old api compat
+        action.field = OFPMatchField.parser(buf, offset + 4)
+
+        return action
+
+    def serialize(self, buf, offset):
+        # old api compat
+        if self._composed_with_old_api():
+            return self.serialize_old(buf, offset)
+
+        n, value, mask = ofproto.oxm_from_user(self.key, self.value)
+        len_ = ofproto.oxm_serialize(n, value, mask, buf, offset + 4)
+        self.len = utils.round_up(4 + len_, 8)
+        msg_pack_into('!HH', buf, offset, self.type, self.len)
+        pad_len = self.len - (4 + len_)
+        ofproto_parser.msg_pack_into("%dx" % pad_len, buf, offset + 4 + len_)
+
+    # XXX old api compat
+    def serialize_old(self, buf, offset):
+        len_ = ofproto.OFP_ACTION_SET_FIELD_SIZE + self.field.oxm_len()
+        self.len = utils.round_up(len_, 8)
+        pad_len = self.len - len_
+
+        msg_pack_into('!HH', buf, offset, self.type, self.len)
+        self.field.serialize(buf, offset + 4)
+        offset += len_
+        ofproto_parser.msg_pack_into("%dx" % pad_len, buf, offset)
+
+    # XXX old api compat
+    def _composed_with_old_api(self):
+        return not hasattr(self, 'value')
+
+    def to_jsondict(self):
+        # XXX old api compat
+        if self._composed_with_old_api():
+            # copy object first because serialize_old is destructive
+            o2 = OFPActionSetField(self.field)
+            # serialize and parse to fill new fields
+            buf = bytearray()
+            o2.serialize(buf, 0)
+            o = OFPActionSetField.parser(str(buf), 0)
+        else:
+            o = self
+        return {
+            self.__class__.__name__: {
+                'field': ofproto.oxm_to_jsondict(self.key, self.value)
+            }
+        }
+
+    @classmethod
+    def from_jsondict(cls, dict_):
+        k, v = ofproto.oxm_from_jsondict(dict_['field'])
+        o = OFPActionSetField(**{k: v})
+
+        # XXX old api compat
+        # serialize and parse to fill old attributes
+        buf = bytearray()
+        o.serialize(buf, 0)
+        return OFPActionSetField.parser(str(buf), 0)
+
+    # XXX old api compat
+    def __str__(self):
+        # XXX old api compat
+        if self._composed_with_old_api():
+            # copy object first because serialize_old is destructive
+            o2 = OFPActionSetField(self.field)
+            # serialize and parse to fill new fields
+            buf = bytearray()
+            o2.serialize(buf, 0)
+            o = OFPActionSetField.parser(str(buf), 0)
+        else:
+            o = self
+        return super(OFPActionSetField, o).__str__()
+
+    __repr__ = __str__
+
+    def stringify_attrs(self):
+        yield (self.key, self.value)
-- 
1.8.4


------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today. 
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to