backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / lib / packet / gre.py
1 # Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 import struct
17
18 from ryu.lib.pack_utils import msg_pack_into
19 from . import packet_base
20 from . import packet_utils
21 from . import ether_types
22
23
24 GRE_CHECKSUM_FLG = 1 << 7
25 GRE_KEY_FLG = 1 << 5
26 GRE_SEQUENCE_NUM_FLG = 1 << 4
27
28
29 class gre(packet_base.PacketBase):
30     """GRE (RFC2784,RFC2890) header encoder/decoder class.
31
32     An instance has the following attributes at least.
33     Most of them are same to the on-wire counterparts but in host byte order.
34     __init__ takes the corresponding args in this order.
35
36     ============== ========================================================
37     Attribute      Description
38     ============== ========================================================
39     version        Version.
40     protocol       Protocol Type field.
41                    The Protocol Type is defined as "ETHER TYPES".
42     checksum       Checksum field(optional).
43                    When you set a value other than None,
44                    this field will be automatically calculated.
45     key            Key field(optional)
46                    This field is intended to be used for identifying
47                    an individual traffic flow within a tunnel.
48     vsid           Virtual Subnet ID field(optional)
49                    This field is a 24-bit value that is used
50                    to identify the NVGRE-based Virtual Layer 2 Network.
51     flow_id        FlowID field(optional)
52                    This field is an 8-bit value that is used to provide
53                    per-flow entropy for flows in the same VSID.
54     seq_number     Sequence Number field(optional)
55     ============== ========================================================
56     """
57     _PACK_STR = "!BBH"
58     _CHECKSUM_PACK_STR = "!H2x"
59     _KEY_PACK_STR = "!I"
60     _SEQNUM_PACK_STR = "!I"
61     _MIN_LEN = struct.calcsize(_PACK_STR)
62     _CHECKSUM_LEN = struct.calcsize(_CHECKSUM_PACK_STR)
63     _KEY_LEN = struct.calcsize(_KEY_PACK_STR)
64     _SEQNUM_PACK_LEN = struct.calcsize(_SEQNUM_PACK_STR)
65
66     # GRE header
67     #  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
68     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69     # |C| |K|S| Reserved0       | Ver |         Protocol Type         |
70     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71     # |      Checksum (optional)      |       Reserved1 (Optional)    |
72     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73     # |                         Key (optional)                        |
74     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75     # |                 Sequence Number (Optional)                    |
76     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77
78     def __init__(self, version=0, protocol=ether_types.ETH_TYPE_IP,
79                  checksum=None, key=None, vsid=None, flow_id=None,
80                  seq_number=None):
81         super(gre, self).__init__()
82
83         self.version = version
84         self.protocol = protocol
85         self.checksum = checksum
86         self.seq_number = seq_number
87
88         if key is not None:
89             self._key = key
90             self._vsid = self._key >> 8
91             self._flow_id = self._key & 0xff
92         elif (vsid is not None) and (flow_id is not None):
93             self._key = vsid << 8 | flow_id
94             self._vsid = vsid
95             self._flow_id = flow_id
96         else:
97             self._key = None
98             self._vsid = None
99             self._flow_id = None
100
101     @property
102     def key(self):
103         return self._key
104
105     @key.setter
106     def key(self, key):
107         if key is not None:
108             self._key = key
109             self._vsid = self._key >> 8
110             self._flow_id = self._key & 0xff
111         else:
112             self._key = None
113             self._vsid = None
114             self._flow_id = None
115
116     @property
117     def vsid(self):
118         return self._vsid
119
120     @vsid.setter
121     def vsid(self, vsid):
122         self._key = vsid << 8 | (self._key & 0xff)
123         self._vsid = vsid
124
125     @property
126     def flow_id(self):
127         return self._flow_id
128
129     @flow_id.setter
130     def flow_id(self, flow_id):
131         self._key = (self._key & 0xffffff00) | flow_id
132         self._flow_id = flow_id
133
134     @classmethod
135     def parser(cls, buf):
136         present, version, protocol = struct.unpack_from(cls._PACK_STR, buf)
137         gre_offset = gre._MIN_LEN
138         checksum = None
139         key = None
140         seq_number = None
141
142         if present & GRE_CHECKSUM_FLG:
143             checksum, = struct.unpack_from(cls._CHECKSUM_PACK_STR,
144                                            buf, gre_offset)
145             gre_offset += cls._CHECKSUM_LEN
146         if present & GRE_KEY_FLG:
147             key, = struct.unpack_from(cls._KEY_PACK_STR, buf, gre_offset)
148             gre_offset += cls._KEY_LEN
149         if present & GRE_SEQUENCE_NUM_FLG:
150             seq_number, = struct.unpack_from(cls._SEQNUM_PACK_STR,
151                                              buf, gre_offset)
152             gre_offset += cls._SEQNUM_PACK_LEN
153
154         msg = cls(version=version, protocol=protocol, checksum=checksum,
155                   key=key, seq_number=seq_number)
156
157         from . import ethernet
158         gre._TYPES = ethernet.ethernet._TYPES
159         gre.register_packet_type(ethernet.ethernet,
160                                  ether_types.ETH_TYPE_TEB)
161
162         return msg, gre.get_packet_type(protocol), buf[gre_offset:]
163
164     def serialize(self, payload=None, prev=None):
165         present = 0
166         hdr = bytearray()
167         optional = bytearray()
168
169         if self.checksum is not None:
170             present |= GRE_CHECKSUM_FLG
171
172             # For purposes of computing the checksum,
173             # the value of the checksum field is zero.
174             # Also, because Reserved1 is always 0x00 of 2 bytes,
175             # Set in conjunction with checksum.
176             optional += b'\x00' * self._CHECKSUM_LEN
177
178         if self._key is not None:
179             present |= GRE_KEY_FLG
180             optional += struct.pack(self._KEY_PACK_STR, self._key)
181
182         if self.seq_number is not None:
183             present |= GRE_SEQUENCE_NUM_FLG
184             optional += struct.pack(self._SEQNUM_PACK_STR, self.seq_number)
185
186         msg_pack_into(self._PACK_STR, hdr, 0, present, self.version,
187                       self.protocol)
188
189         hdr += optional
190
191         if self.checksum:
192             self.checksum = packet_utils.checksum(hdr)
193             struct.pack_into(self._CHECKSUM_PACK_STR, hdr, self._MIN_LEN,
194                              self.checksum)
195
196         return hdr
197
198
199 def nvgre(version=0, vsid=0, flow_id=0):
200     """
201     Generate instance of GRE class with information for NVGRE (RFC7637).
202
203     :param version: Version.
204     :param vsid: Virtual Subnet ID.
205     :param flow_id: FlowID.
206     :return: Instance of GRE class with information for NVGRE.
207     """
208
209     # NVGRE header
210     #  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
211     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
212     # |0| |1|0|   Reserved0     | Ver |   Protocol Type 0x6558        |
213     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
214     # |               Virtual Subnet ID (VSID)        |    FlowID     |
215     # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
216     return gre(version=version, protocol=ether_types.ETH_TYPE_TEB,
217                vsid=vsid, flow_id=flow_id)