backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / lib / packet / openflow.py
1 # Copyright (C) 2017 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 import stringify
19 from . import packet_base
20
21
22 class openflow(packet_base.PacketBase):
23     """OpenFlow message encoder/decoder class.
24
25     An instance has the following attributes at least.
26
27     ============== =========================================================
28     Attribute      Description
29     ============== =========================================================
30     msg            An instance of OpenFlow message (see :ref:`ofproto_ref`)
31                    or an instance of OFPUnparseableMsg if failed to parse
32                    packet as OpenFlow message.
33     ============== =========================================================
34     """
35
36     PACK_STR = '!BBHI'
37     _MIN_LEN = struct.calcsize(PACK_STR)
38
39     def __init__(self, msg):
40         super(openflow, self).__init__()
41         self.msg = msg
42
43     @classmethod
44     def parser(cls, buf):
45         from ryu.ofproto import ofproto_parser
46         from ryu.ofproto import ofproto_protocol
47
48         (version, msg_type, msg_len, xid) = ofproto_parser.header(buf)
49
50         msg_parser = ofproto_parser._MSG_PARSERS.get(version)
51         if msg_parser is None:
52             msg = OFPUnparseableMsg(
53                 None, version, msg_type, msg_len, xid,
54                 buf[cls._MIN_LEN:msg_len])
55             return cls(msg), cls, buf[msg_len:]
56
57         datapath = ofproto_protocol.ProtocolDesc(version=version)
58
59         try:
60             msg = msg_parser(datapath, version, msg_type, msg_len, xid,
61                              buf[:msg_len])
62         except:
63             msg = OFPUnparseableMsg(
64                 datapath, version, msg_type, msg_len, xid,
65                 buf[datapath.ofproto.OFP_HEADER_SIZE:msg_len])
66
67         return cls(msg), cls, buf[msg_len:]
68
69     def serialize(self, _payload, _prev):
70         self.msg.serialize()
71         return self.msg.buf
72
73
74 class OFPUnparseableMsg(stringify.StringifyMixin):
75     """Unparseable OpenFlow message encoder class.
76
77     An instance has the following attributes at least.
78
79     ============== ======================================================
80     Attribute      Description
81     ============== ======================================================
82     datapath       A ryu.ofproto.ofproto_protocol.ProtocolDesc instance
83                    for this message or None if OpenFlow protocol version
84                    is unsupported version.
85     version        OpenFlow protocol version
86     msg_type       Type of OpenFlow message
87     msg_len        Length of the message
88     xid            Transaction id
89     body           OpenFlow body data
90     ============== ======================================================
91
92     .. Note::
93
94         "datapath" attribute is different from
95         ryu.controller.controller.Datapath.
96         So you can not use "datapath" attribute to send OpenFlow messages.
97         For example, "datapath" attribute does not have send_msg method.
98     """
99
100     def __init__(self, datapath, version, msg_type, msg_len, xid, body):
101         self.datapath = datapath
102         self.version = version
103         self.msg_type = msg_type
104         self.msg_len = msg_len
105         self.xid = xid
106         self.body = body
107         self.buf = None
108
109     def serialize(self):
110         self.buf = struct.pack(
111             openflow.PACK_STR,
112             self.version, self.msg_type, self.msg_len, self.xid)
113         self.buf += self.body