f9dfeb9c6777b30ff5fbec0a1d9179084935f079
[oonf.git] / src-plugins / generic / dlep / dlep_session.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #ifndef _DLEP_SESSION_H_
47 #define _DLEP_SESSION_H_
48
49 struct dlep_session;
50 struct dlep_writer;
51
52 #include "common/autobuf.h"
53 #include "common/avl.h"
54 #include "common/common_types.h"
55 #include "common/netaddr.h"
56 #include "subsystems/oonf_layer2.h"
57 #include "subsystems/oonf_stream_socket.h"
58 #include "subsystems/oonf_timer.h"
59 #include "subsystems/os_interface.h"
60
61 #include "dlep/dlep_extension.h"
62 #include "dlep/dlep_iana.h"
63
64 /**
65  * Return codes for DLEP parser
66  */
67 enum dlep_parser_error
68 {
69   /*! parsing successful */
70   DLEP_NEW_PARSER_OKAY = 0,
71
72   /*! Signal terminates session, session is now invalid! */
73   DLEP_NEW_PARSER_TERMINDATED = -1,
74
75   /*! signal too short, incomplete TLV header */
76   DLEP_NEW_PARSER_INCOMPLETE_TLV_HEADER = -2,
77
78   /*! signal too short, incomplete TLV */
79   DLEP_NEW_PARSER_INCOMPLETE_TLV = -3,
80
81   /*! TLV type is not supported by session */
82   DLEP_NEW_PARSER_UNSUPPORTED_TLV = -4,
83
84   /*! TLV length is not supported */
85   DLEP_NEW_PARSER_ILLEGAL_TLV_LENGTH = -5,
86
87   /*! mandatory TLV is missing */
88   DLEP_NEW_PARSER_MISSING_MANDATORY_TLV = -6,
89
90   /*! this TLV must not be used more than once */
91   DLEP_NEW_PARSER_DUPLICATE_TLV = -7,
92
93   /*! out of memory error */
94   DLEP_NEW_PARSER_OUT_OF_MEMORY = -8,
95
96   /*! internal parser error, inconsistent data structures */
97   DLEP_NEW_PARSER_INTERNAL_ERROR = -9,
98 };
99
100 /**
101  * Definition of a TLV that has been parsed by DLEP
102  */
103 struct dlep_parser_tlv {
104   /*! tlv id */
105   uint16_t id;
106
107   /*! index of first session value for tlv, -1 if none */
108   int32_t tlv_first;
109
110   /*! index of last session value for tlv, -1 if none */
111   int32_t tlv_last;
112
113   /*! minimal length of tlv */
114   uint16_t length_min;
115
116   /*! maximal length of tlv */
117   uint16_t length_max;
118
119   /*! used to remove unsupported TLVs */
120   bool remove;
121
122   /*! node for session tlv tree */
123   struct avl_node _node;
124 };
125
126 /**
127  * header for binary data gathered for a TLV of a certain type
128  */
129 struct dlep_parser_value {
130   /*! index of next session value */
131   int32_t tlv_next;
132
133   /*! index of value within signal buffer */
134   uint16_t index;
135
136   /*! length of tlv in bytes */
137   uint16_t length;
138 };
139
140 /**
141  * Session for the DLEP tlv parser
142  */
143 struct dlep_session_parser {
144   /*! tree of allowed TLVs for this session */
145   struct avl_tree allowed_tlvs;
146
147   /*! array of TLV values */
148   struct dlep_parser_value *values;
149
150   /*! size of array for TLV value headers */
151   size_t value_max_count;
152
153   /*! array of active dlep extensions */
154   struct dlep_extension *extensions[DLEP_EXTENSION_BASE_COUNT + DLEP_EXTENSION_COUNT];
155
156   /*! number of active dlep extensions */
157   size_t extension_count;
158
159   /*! start of signal tlvs that is has been parsed */
160   const uint8_t *tlv_ptr;
161
162   /*! neighbor MAC a signal is referring to */
163   struct netaddr signal_neighbor_mac;
164 };
165
166 /**
167  * DLEP writer for TLV data
168  */
169 struct dlep_writer {
170   /*! output buffer for binary data */
171   struct autobuf *out;
172
173   /*! type of signal */
174   uint16_t signal_type;
175
176   /*! index of first byte of signal */
177   size_t signal_start;
178 };
179
180 /**
181  * Status of a DLEP neighbor
182  */
183 enum dlep_neighbor_state
184 {
185   /*! neighbor has not yet been used in session */
186   DLEP_NEIGHBOR_IDLE = 0,
187
188   /*! a destination up has been sent */
189   DLEP_NEIGHBOR_UP_SENT = 1,
190
191   /*! a destination up has been sent and acked */
192   DLEP_NEIGHBOR_UP_ACKED = 2,
193
194   /*! a destination down has been sent */
195   DLEP_NEIGHBOR_DOWN_SENT = 3,
196
197   /*! a destination down has been sent and acked*/
198   DLEP_NEIGHBOR_DOWN_ACKED = 4,
199 };
200
201 /**
202  * Neighbor that has been used in a DLEP session
203  */
204 struct dlep_local_neighbor {
205   /**
206    * mac address of the endpoint of the neighbor
207    * (might be proxied ethernet)
208    * it might also have a link ID
209    */
210   struct oonf_layer2_neigh_key key;
211
212   /*! state of neighbor */
213   enum dlep_neighbor_state state;
214
215   /*! true if the neighbor changes since the last update */
216   bool changed;
217
218   /*! true if iterative updates are be used for destination IPs */
219   bool destination_ip_iterative;
220
221   /*! mac address (plus link ID) of the neighbors wireless interface */
222   struct oonf_layer2_neigh_key neigh_key;
223
224   /*! back-pointer to dlep session */
225   struct dlep_session *session;
226
227   /*! timeout for acknowledgement signal */
228   struct oonf_timer_instance _ack_timeout;
229
230   /*! tree of modifications which should be put into the next destination update */
231   struct avl_tree _ip_prefix_modification;
232
233   /*! hook into the sessions tree of neighbors */
234   struct avl_node _node;
235 };
236
237 /**
238  * Configuration of a dlep session
239  */
240 struct dlep_session_config {
241   /*! peer type of local session */
242   char *peer_type;
243
244   /*! discovery interval */
245   uint64_t discovery_interval;
246
247   /*! heartbeat settings for our heartbeats */
248   uint64_t heartbeat_interval;
249
250   /*! true if normal neighbors should be sent with DLEP */
251   bool send_neighbors;
252
253   /*! true if proxied neighbors should be sent with DLEP */
254   bool send_proxied;
255 };
256
257 /**
258  * Records the state of the peer regarding PEER UPDATE messages
259  */
260 enum dlep_peer_state
261 {
262   DLEP_PEER_NOT_CONNECTED,
263   DLEP_PEER_WAIT_FOR_INIT,
264   DLEP_PEER_WAIT_FOR_UPDATE_ACK,
265   DLEP_PEER_SEND_UPDATE,
266   DLEP_PEER_IDLE,
267   DLEP_PEER_TERMINATED,
268 };
269
270 /**
271  * Generic DLEP session, might be radio or router
272  */
273 struct dlep_session {
274   /*! copy of local configuration */
275   struct dlep_session_config cfg;
276
277   /*! restrict incoming signals to a special signal */
278   enum dlep_signals restrict_signal;
279
280   /*! initialize restrict signal with this variable after processing if not 0 */
281   enum dlep_signals next_restrict_signal;
282
283   /*! true if this is a radio session */
284   bool radio;
285
286   /*! true if LID tagged neighbor information can be transmitted over the link */
287   bool allow_lids;
288
289   /*! parser for this dlep session */
290   struct dlep_session_parser parser;
291
292   /*! signal writer*/
293   struct dlep_writer writer;
294
295   /*! tree of local neighbors being processed by DLEP */
296   struct avl_tree local_neighbor_tree;
297
298   /*! oonf layer2 origin for dlep session */
299   const struct oonf_layer2_origin *l2_origin;
300
301   /*! oonf layer2 origin for dlep session defaults */
302   const struct oonf_layer2_origin *l2_default_origin;
303
304   /*! send content of output buffer */
305   void (*cb_send_buffer)(struct dlep_session *, int af_family);
306
307   /*! terminate the current session */
308   void (*cb_end_session)(struct dlep_session *);
309
310   /*! handle timeout for destination */
311   void (*cb_destination_timeout)(struct dlep_session *, struct dlep_local_neighbor *);
312
313   /*! log source for usage of this session */
314   enum oonf_log_source log_source;
315
316   /*! local layer2 data interface */
317   struct os_interface_listener l2_listener;
318
319   /*! timer to generate discovery/heartbeats */
320   struct oonf_timer_instance local_event_timer;
321
322   /*! keep track of remote heartbeats */
323   struct oonf_timer_instance remote_heartbeat_timeout;
324
325   /*! rate of remote heartbeats */
326   uint64_t remote_heartbeat_interval;
327
328   /*! remote endpoint of current communication */
329   union netaddr_socket remote_socket;
330
331   /*! timeout for acknowledgement signal */
332   struct oonf_timer_instance _ack_timeout;
333
334   /*! true if we cannot send a peer update at the moment */
335   enum dlep_peer_state _peer_state;
336
337   /*! tree of modifications which should be put into the next peer update */
338   struct avl_tree _ip_prefix_modification;
339 };
340
341 void dlep_session_init(void);
342
343 int dlep_session_add(struct dlep_session *session, const char *l2_ifname, const struct oonf_layer2_origin *l2_origin,
344   const struct oonf_layer2_origin *l2_default_origin, struct autobuf *out, bool radio,
345   int (*if_changed)(struct os_interface_listener *), enum oonf_log_source);
346 void dlep_session_remove(struct dlep_session *session);
347 void dlep_session_terminate(struct dlep_session *session, enum dlep_status status, const char *status_text);
348
349 int dlep_session_update_extensions(struct dlep_session *session, const uint8_t *extvalues, size_t extcount, bool radio);
350 enum oonf_stream_session_state dlep_session_process_tcp(
351   struct oonf_stream_session *tcp_session, struct dlep_session *session);
352 ssize_t dlep_session_process_buffer(struct dlep_session *session, const void *buffer, size_t length, bool is_udp);
353 ssize_t dlep_session_process_signal(struct dlep_session *session, const void *buffer, size_t length, bool is_udp);
354 int dlep_session_generate_signal(struct dlep_session *session, int32_t signal, const struct oonf_layer2_neigh_key *neighbor);
355 int dlep_session_generate_signal_status(struct dlep_session *session, int32_t signal, const struct oonf_layer2_neigh_key *neighbor,
356   enum dlep_status status, const char *msg);
357 struct dlep_parser_value *dlep_session_get_tlv_value(struct dlep_session *session, uint16_t tlvtype);
358
359 struct dlep_local_neighbor *dlep_session_add_local_neighbor(struct dlep_session *session, const struct oonf_layer2_neigh_key *key);
360 void dlep_session_remove_local_neighbor(struct dlep_session *session, struct dlep_local_neighbor *local);
361 struct oonf_layer2_neigh *dlep_session_get_local_l2_neighbor(struct dlep_session *session, const struct oonf_layer2_neigh_key *key);
362 struct oonf_layer2_neigh *dlep_session_get_l2_from_neighbor(struct dlep_local_neighbor *dlep_neigh);
363
364 /**
365  * get the dlep session tlv
366  * @param parser dlep session parser
367  * @param tlvtype tlvtype
368  * @return tlv parser information, NULL if not available
369  */
370 static INLINE struct dlep_parser_tlv *
371 dlep_parser_get_tlv(struct dlep_session_parser *parser, uint16_t tlvtype) {
372   struct dlep_parser_tlv *tlv;
373   return avl_find_element(&parser->allowed_tlvs, &tlvtype, tlv, _node);
374 }
375
376 /**
377  * Get value of first appearance of a TLV
378  * @param session dlep session parser
379  * @param tlv dlep session tlv
380  * @return dlep tlv value, NULL if no value available
381  */
382 static INLINE struct dlep_parser_value *
383 dlep_session_get_tlv_first_value(struct dlep_session *session, struct dlep_parser_tlv *tlv) {
384   if (tlv->tlv_first == -1) {
385     return NULL;
386   }
387   return &session->parser.values[tlv->tlv_first];
388 }
389
390 /**
391  * Get the next value of a TLV
392  * @param session dlep session parser
393  * @param value current dlep parser value
394  * @return next dlep tlv value, NULL if no further values
395  */
396 static INLINE struct dlep_parser_value *
397 dlep_session_get_next_tlv_value(struct dlep_session *session, struct dlep_parser_value *value) {
398   if (value->tlv_next == -1) {
399     return NULL;
400   }
401   return &session->parser.values[value->tlv_next];
402 }
403
404 /**
405  * Get the binary data of a tlv
406  * @param parser dlep session parser
407  * @param value dlep tlv value
408  * @return binary data pointer
409  */
410 static INLINE const uint8_t *
411 dlep_parser_get_tlv_binary(struct dlep_session_parser *parser, struct dlep_parser_value *value) {
412   return &parser->tlv_ptr[value->index];
413 }
414
415 /**
416  * Shortcut for getting the binary data of a TLV for a session
417  * @param session dlep session
418  * @param value dlep tlv value
419  * @return binary data pointer
420  */
421 static INLINE const uint8_t *
422 dlep_session_get_tlv_binary(struct dlep_session *session, struct dlep_parser_value *value) {
423   return &session->parser.tlv_ptr[value->index];
424 }
425
426 /**
427  * Get a DLEP neighbor
428  * @param session dlep session
429  * @param key neighbor MAC address plus link ID
430  * @return DLEP neighbor, NULL if not found
431  */
432 static INLINE struct dlep_local_neighbor *
433 dlep_session_get_local_neighbor(struct dlep_session *session, const struct oonf_layer2_neigh_key *key) {
434   struct dlep_local_neighbor *local;
435   return avl_find_element(&session->local_neighbor_tree, key, local, _node);
436 }
437
438 #endif /* _DLEP_SESSION_H_ */