Update git submodules
[docs.git] / docs / developer-guide / netide-developer-guide.rst
1 .. _netide-dev-guide:
2
3 NetIDE Developer Guide
4 ======================
5
6 Overview
7 --------
8
9 The NetIDE Network Engine enables portability and cooperation inside a
10 single network by using a client/server multi-controller SDN
11 architecture. Separate "Client SDN Controllers" host the various SDN
12 Applications with their access to the actual physical network abstracted
13 and coordinated through a single "Server SDN Controller", in this
14 instance OpenDaylight. This allows applications written for
15 Ryu/Floodlight/Pyretic to execute on OpenDaylight managed
16 infrastructure.
17
18 The "Network Engine" is modular by design:
19
20 -  An OpenDaylight plugin, "shim", sends/receives messages to/from
21    subscribed SDN Client Controllers. This consumes the ODL OpenFlow
22    Plugin
23
24 -  An initial suite of SDN Client Controller "Backends": Floodlight,
25    Ryu, Pyretic. Further controllers may be added over time as the
26    engine is extensible.
27
28 The Network Engine provides a compatibility layer capable of translating
29 calls of the network applications running on top of the client
30 controllers, into calls for the server controller framework. The
31 communication between the client and the server layers is achieved
32 through the NetIDE intermediate protocol, which is an application-layer
33 protocol on top of TCP that transmits the network control/management
34 messages from the client to the server controller and vice-versa.
35 Between client and server controller sits the Core Layer which also
36 "speaks" the intermediate protocol. The core layer implements three main
37 functions:
38
39 i.   interfacing with the client backends and server shim, controlling
40      the lifecycle of controllers as well as modules in them,
41
42 ii.  orchestrating the execution of individual modules (in one client
43      controller) or complete applications (possibly spread across
44      multiple client controllers),
45
46 iii. interfacing with the tools.
47
48 .. figure:: ./images/netide/arch-engine.jpg
49    :alt: NetIDE Network Engine Architecture
50
51    NetIDE Network Engine Architecture
52
53 NetIDE Intermediate Protocol
54 ----------------------------
55
56 The Intermediate Protocol serves several needs, it has to:
57
58 i.   carry control messages between core and shim/backend, e.g., to
59      start up/take down a particular module, providing unique
60      identifiers for modules,
61
62 ii.  carry event and action messages between shim, core, and backend,
63      properly demultiplexing such messages to the right module based on
64      identifiers,
65
66 iii. encapsulate messages specific to a particular SBI protocol version
67      (e.g., OpenFlow 1.X, NETCONF, etc.) towards the client controllers
68      with proper information to recognize these messages as such.
69
70 The NetIDE packages can be added as dependencies in Maven projects by
71 putting the following code in the *pom.xml* file.
72
73 ::
74
75     <dependency>
76         <groupId>org.opendaylight.netide</groupId>
77         <artifactId>api</artifactId>
78         <version>${NETIDE_VERSION}</version>
79     </dependency>
80
81 The current stable version for NetIDE is ``0.2.0-Boron``.
82
83 Protocol specification
84 ~~~~~~~~~~~~~~~~~~~~~~
85
86 Messages of the NetIDE protocol contain two basic elements: the NetIDE
87 header and the data (or payload). The NetIDE header, described below, is
88 placed before the payload and serves as the communication and control
89 link between the different components of the Network Engine. The payload
90 can contain management messages, used by the components of the Network
91 Engine to exchange relevant information, or control/configuration
92 messages (such as OpenFlow, NETCONF, etc.) crossing the Network Engine
93 generated by either network application modules or by the network
94 elements.
95
96 The NetIDE header is defined as follows:
97
98 ::
99
100      0                   1                   2                   3
101      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
102     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103     |   netide_ver  |      type     |             length            |
104     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105     |                         xid                                   |
106     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107     |                       module_id                               |
108     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109     |                                                               |
110     +                     datapath_id                               +
111     |                                                               |
112     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113
114 where each tick mark represents one bit position. Alternatively, in a
115 C-style coding format, the NetIDE header can be represented with the
116 following structure:
117
118 ::
119
120     struct netide_header {
121         uint8_t netide_ver ;
122         uint8_t type ;
123         uint16_t length ;
124         uint32_t xid
125         uint32_t module_id
126         uint64_t datapath_id
127     };
128
129 -  ``netide_ver`` is the version of the NetIDE protocol (the current
130    version is v1.2, which is identified with value 0x03).
131
132 -  ``length`` is the total length of the payload in bytes.
133
134 -  ``type`` contains a code that indicates the type of the message
135    according with the following values:
136
137    ::
138
139        enum type {
140            NETIDE_HELLO = 0x01 ,
141            NETIDE_ERROR = 0x02 ,
142            NETIDE_MGMT = 0x03 ,
143            MODULE_ANNOUNCEMENT = 0x04 ,
144            MODULE_ACKNOWLEDGE = 0x05 ,
145            NETIDE_HEARTBEAT = 0x06 ,
146            NETIDE_OPENFLOW = 0x11 ,
147            NETIDE_NETCONF = 0x12 ,
148            NETIDE_OPFLEX = 0x13
149        };
150
151 -  ``datapath_id`` is a 64-bit field that uniquely identifies the
152    network elements.
153
154 -  ``module_id`` is a 32-bits field that uniquely identifies Backends
155    and application modules running on top of each client controller. The
156    composition mechanism in the core layer leverages on this field to
157    implement the correct execution flow of these modules.
158
159 -  ``xid`` is the transaction identifier associated to the each message.
160    Replies must use the same value to facilitate the pairing.
161
162 Module announcement
163 ~~~~~~~~~~~~~~~~~~~
164
165 The first operation performed by a Backend is registering itself and the
166 modules that it is running to the Core. This is done by using the
167 ``MODULE_ANNOUNCEMENT`` and ``MODULE_ACKNOWLEDGE`` message types. As a
168 result of this process, each Backend and application module can be
169 recognized by the Core through an identifier (the ``module_id``) placed
170 in the NetIDE header. First, a Backend registers itself by using the
171 following schema: backend-<platform name>-<pid>.
172
173 For example,odule a Ryu Backend will register by using the following
174 name in the message backend-ryu-12345 where 12345 is the process ID of
175 the registering instance of the Ryu platform. The format of the message
176 is the following:
177
178 ::
179
180     struct NetIDE_message {
181         netide_ver = 0x03
182         type = MODULE_ANNOUNCEMENT
183         length = len(" backend -< platform_name >-<pid >")
184         xid = 0
185         module_id = 0
186         datapath_id = 0
187         data = " backend -< platform_name >-<pid >"
188     }
189
190 The answer generated by the Core will include a ``module_id`` number and
191 the Backend name in the payload (the same indicated in the
192 ``MODULE_ANNOUNCEMENT`` message):
193
194 ::
195
196     struct NetIDE_message {
197         netide_ver = 0x03
198         type = MODULE_ACKNOWLEDGE
199         length = len(" backend -< platform_name >-<pid >")
200         xid = 0
201         module_id = MODULE_ID
202         datapath_id = 0
203         data = " backend -< platform_name >-<pid >"
204     }
205
206 Once a Backend has successfully registered itself, it can start
207 registering its modules with the same procedure described above by
208 indicating the name of the module in the data (e.g. data="Firewall").
209 From this point on, the Backend will insert its own ``module_id`` in the
210 header of the messages it generates (e.g. heartbeat, hello messages,
211 OpenFlow echo messages from the client controllers, etc.). Otherwise, it
212 will encapsulate the control/configuration messages (e.g. FlowMod,
213 PacketOut, FeatureRequest, NETCONF request, etc.) generated by network
214 application modules with the specific +module\_id+s.
215
216 Heartbeat
217 ~~~~~~~~~
218
219 The heartbeat mechanism has been introduced after the adoption of the
220 ZeroMQ messaging queuing library to transmit the NetIDE messages.
221 Unfortunately, the ZeroMQ library does not offer any mechanism to find
222 out about disrupted connections (and also completely unresponsive
223 peers). This limitation of the ZeroMQ library can be an issue for the
224 Core’s composition mechanism and for the tools connected to the Network
225 Engine, as they cannot understand when an client controller disconnects
226 or crashes. As a consequence, Backends must periodically send (let’s say
227 every 5 seconds) a "heartbeat" message to the Core. If the Core does not
228 receive at least one "heartbeat" message from the Backend within a
229 certain timeframe, the Core considers it disconnected, removes all the
230 related data from its memory structures and informs the relevant tools.
231 The format of the message is the following:
232
233 ::
234
235     struct NetIDE_message {
236         netide_ver = 0x03
237         type = NETIDE_HEARTBEAT
238         length = 0
239         xid = 0
240         module_id = backend -id
241         datapath_id = 0
242         data = 0
243     }
244
245 Handshake
246 ~~~~~~~~~
247
248 Upon a successful connection with the Core, the client controller must
249 immediately send a hello message with the list of the control and/or
250 management protocols needed by the applications deployed on top of it.
251
252 ::
253
254     struct NetIDE_message {
255         struct netide_header header ;
256         uint8 data [0]
257     };
258
259 The header contains the following values:
260
261 -  ``netide ver=0x03``
262
263 -  ``type=NETIDE_HELLO``
264
265 -  ``length=2*NR_PROTOCOLS``
266
267 -  ``data`` contains one 2-byte word (in big endian order) for each
268    protocol, with the first byte containing the code of the protocol
269    according to the above enum, while the second byte in- dictates the
270    version of the protocol (e.g. according to the ONF specification,
271    0x01 for OpenFlow v1.0, 0x02 for OpenFlow v1.1, etc.). NETCONF
272    version is marked with 0x01 that refers to the specification in the
273    RFC6241, while OpFlex version is marked with 0x00 since this protocol
274    is still in work-in-progress stage.
275
276 The Core relays hello messages to the server controller which responds
277 with another hello message containing the following:
278
279 -  ``netide ver=0x03``
280
281 -  ``type=NETIDE_HELLO``
282
283 -  ``length=2*NR_PROTOCOLS``
284
285 If at least one of the protocols requested by the client is supported.
286 In particular, ``data`` contains the codes of the protocols that match
287 the client’s request (2-bytes words, big endian order). If the hand-
288 shake fails because none of the requested protocols is supported by the
289 server controller, the header of the answer is as follows:
290
291 -  ``netide ver=0x03``
292
293 -  ``type=NETIDE_ERROR``
294
295 -  ``length=2*NR_PROTOCOLS``
296
297 -  ``data`` contains the codes of all the protocols supported by the
298    server controller (2-bytes words, big endian order). In this case,
299    the TCP session is terminated by the server controller just after the
300    answer is received by the client. \`
301