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