Signed-off-by: Shinpei Muraoka <shinpei.mura...@gmail.com>
---
 ryu/lib/packet/gre.py | 128 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 108 insertions(+), 20 deletions(-)

diff --git a/ryu/lib/packet/gre.py b/ryu/lib/packet/gre.py
index c22032e..a62f0d1 100644
--- a/ryu/lib/packet/gre.py
+++ b/ryu/lib/packet/gre.py
@@ -15,10 +15,10 @@
 
 import struct
 
+from ryu.lib.pack_utils import msg_pack_into
 from . import packet_base
 from . import packet_utils
-from . import ether_types as ether
-from ryu.lib.pack_utils import msg_pack_into
+from . import ether_types
 
 
 GRE_CHECKSUM_FLG = 1 << 7
@@ -36,6 +36,7 @@ class gre(packet_base.PacketBase):
     ============== ========================================================
     Attribute      Description
     ============== ========================================================
+    version        Version.
     protocol       Protocol Type field.
                    The Protocol Type is defined as "ETHER TYPES".
     checksum       Checksum field(optional).
@@ -44,6 +45,12 @@ class gre(packet_base.PacketBase):
     key            Key field(optional)
                    This field is intended to be used for identifying
                    an individual traffic flow within a tunnel.
+    vsid           Virtual Subnet ID field(optional)
+                   This field is a 24-bit value that is used
+                   to identify the NVGRE-based Virtual Layer 2 Network.
+    flow_id        FlowID field(optional)
+                   This field is an 8-bit value that is used to provide
+                   per-flow entropy for flows in the same VSID.
     seq_number     Sequence Number field(optional)
     ============== ========================================================
     """
@@ -54,16 +61,76 @@ class gre(packet_base.PacketBase):
     _MIN_LEN = struct.calcsize(_PACK_STR)
     _CHECKSUM_LEN = struct.calcsize(_CHECKSUM_PACK_STR)
     _KEY_LEN = struct.calcsize(_KEY_PACK_STR)
-
-    def __init__(self, protocol=ether.ETH_TYPE_IP,
-                 checksum=None, key=None, seq_number=None):
+    _SEQNUM_PACK_LEN = struct.calcsize(_SEQNUM_PACK_STR)
+
+    # GRE header
+    #  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    # |C| |K|S| Reserved0       | Ver |         Protocol Type         |
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    # |      Checksum (optional)      |       Reserved1 (Optional)    |
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    # |                         Key (optional)                        |
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    # |                 Sequence Number (Optional)                    |
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+    def __init__(self, version=0, protocol=ether_types.ETH_TYPE_IP,
+                 checksum=None, key=None, vsid=None, flow_id=None,
+                 seq_number=None):
         super(gre, self).__init__()
 
+        self.version = version
         self.protocol = protocol
         self.checksum = checksum
-        self.key = key
         self.seq_number = seq_number
 
+        if key is not None:
+            self._key = key
+            self._vsid = self._key >> 8
+            self._flow_id = self._key & 0xff
+        elif (vsid is not None) and (flow_id is not None):
+            self._key = vsid << 8 | flow_id
+            self._vsid = vsid
+            self._flow_id = flow_id
+        else:
+            self._key = None
+            self._vsid = None
+            self._flow_id = None
+
+    @property
+    def key(self):
+        return self._key
+
+    @key.setter
+    def key(self, key):
+        if key is not None:
+            self._key = key
+            self._vsid = self._key >> 8
+            self._flow_id = self._key & 0xff
+        else:
+            self._key = None
+            self._vsid = None
+            self._flow_id = None
+
+    @property
+    def vsid(self):
+        return self._vsid
+
+    @vsid.setter
+    def vsid(self, vsid):
+        self._key = vsid << 8 | (self._key & 0xff)
+        self._vsid = vsid
+
+    @property
+    def flow_id(self):
+        return self._flow_id
+
+    @flow_id.setter
+    def flow_id(self, flow_id):
+        self._key = (self._key & 0xffffff00) | flow_id
+        self._flow_id = flow_id
+
     @classmethod
     def parser(cls, buf):
         present, version, protocol = struct.unpack_from(cls._PACK_STR, buf)
@@ -82,25 +149,25 @@ class gre(packet_base.PacketBase):
         if present & GRE_SEQUENCE_NUM_FLG:
             seq_number, = struct.unpack_from(cls._SEQNUM_PACK_STR,
                                              buf, gre_offset)
+            gre_offset += cls._SEQNUM_PACK_LEN
 
-        msg = cls(protocol, checksum, key, seq_number)
+        msg = cls(version=version, protocol=protocol, checksum=checksum,
+                  key=key, seq_number=seq_number)
 
         from . import ethernet
-        # Because the protocol type field could either Ethertype is set,
-        # Set the _TYPES of ethernet, which owns the Ethernet types
-        # available in Ryu.
         gre._TYPES = ethernet.ethernet._TYPES
+        gre.register_packet_type(ethernet.ethernet,
+                                 ether_types.ETH_TYPE_TEB)
 
         return msg, gre.get_packet_type(protocol), buf[gre_offset:]
 
     def serialize(self, payload=None, prev=None):
         present = 0
-        version = 0
         hdr = bytearray()
         optional = bytearray()
 
-        if self.checksum:
-            present += GRE_CHECKSUM_FLG
+        if self.checksum is not None:
+            present |= GRE_CHECKSUM_FLG
 
             # For purposes of computing the checksum,
             # the value of the checksum field is zero.
@@ -108,16 +175,16 @@ class gre(packet_base.PacketBase):
             # Set in conjunction with checksum.
             optional += b'\x00' * self._CHECKSUM_LEN
 
-        if self.key:
-            present += GRE_KEY_FLG
-            optional += struct.pack(self._KEY_PACK_STR, self.key)
+        if self._key is not None:
+            present |= GRE_KEY_FLG
+            optional += struct.pack(self._KEY_PACK_STR, self._key)
 
-        if self.seq_number:
-            present += GRE_SEQUENCE_NUM_FLG
+        if self.seq_number is not None:
+            present |= GRE_SEQUENCE_NUM_FLG
             optional += struct.pack(self._SEQNUM_PACK_STR, self.seq_number)
 
-        msg_pack_into(self._PACK_STR, hdr, 0,
-                      present, version, self.protocol)
+        msg_pack_into(self._PACK_STR, hdr, 0, present, self.version,
+                      self.protocol)
 
         hdr += optional
 
@@ -127,3 +194,24 @@ class gre(packet_base.PacketBase):
                              self.checksum)
 
         return hdr
+
+
+def nvgre(version=0, vsid=0, flow_id=0):
+    """
+    Generate instance of GRE class with information for NVGRE (RFC7637).
+
+    :param version: Version.
+    :param vsid: Virtual Subnet ID.
+    :param flow_id: FlowID.
+    :return: Instance of GRE class with information for NVGRE.
+    """
+
+    # NVGRE header
+    #  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    # |0| |1|0|   Reserved0     | Ver |   Protocol Type 0x6558        |
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    # |               Virtual Subnet ID (VSID)        |    FlowID     |
+    # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    return gre(version=version, protocol=ether_types.ETH_TYPE_TEB,
+               vsid=vsid, flow_id=flow_id)
-- 
2.7.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today.http://sdm.link/intel
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to