1 # Copyright (C) 2017 Nippon Telegraph and Telephone Corporation.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 from ryu.lib import stringify
19 from . import packet_base
22 class openflow(packet_base.PacketBase):
23 """OpenFlow message encoder/decoder class.
25 An instance has the following attributes at least.
27 ============== =========================================================
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 ============== =========================================================
37 _MIN_LEN = struct.calcsize(PACK_STR)
39 def __init__(self, msg):
40 super(openflow, self).__init__()
45 from ryu.ofproto import ofproto_parser
46 from ryu.ofproto import ofproto_protocol
48 (version, msg_type, msg_len, xid) = ofproto_parser.header(buf)
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:]
57 datapath = ofproto_protocol.ProtocolDesc(version=version)
60 msg = msg_parser(datapath, version, msg_type, msg_len, xid,
63 msg = OFPUnparseableMsg(
64 datapath, version, msg_type, msg_len, xid,
65 buf[datapath.ofproto.OFP_HEADER_SIZE:msg_len])
67 return cls(msg), cls, buf[msg_len:]
69 def serialize(self, _payload, _prev):
74 class OFPUnparseableMsg(stringify.StringifyMixin):
75 """Unparseable OpenFlow message encoder class.
77 An instance has the following attributes at least.
79 ============== ======================================================
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
89 body OpenFlow body data
90 ============== ======================================================
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.
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
110 self.buf = struct.pack(
112 self.version, self.msg_type, self.msg_len, self.xid)
113 self.buf += self.body