mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-10 06:46:11 +02:00
packet/gre: Support NVGRE extension
Signed-off-by: Shinpei Muraoka <shinpei.muraoka@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
d1c275ed6f
commit
19e415a19d
@ -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)
|
||||
_SEQNUM_PACK_LEN = struct.calcsize(_SEQNUM_PACK_STR)
|
||||
|
||||
def __init__(self, protocol=ether.ETH_TYPE_IP,
|
||||
checksum=None, key=None, seq_number=None):
|
||||
# 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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user