45bb0822a9d30805145850eda796390a6904cdc7
[oonf.git] / include / oonf / generic / dlep / dlep_extension.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_EXTENSION_H_
47 #define _DLEP_EXTENSION_H_
48
49 struct dlep_extension;
50
51 #include <oonf/libcommon/autobuf.h>
52 #include <oonf/libcommon/avl.h>
53 #include <oonf/oonf.h>
54
55 #include <oonf/subsystems/oonf_layer2.h>
56
57 #include <oonf/generic/dlep/dlep_session.h>
58
59 /**
60  * Extension for a specific DLEP signal
61  */
62 struct dlep_extension_signal {
63   /*! signal id */
64   int32_t id;
65
66   /*! array of supported tlv ids */
67   const uint16_t *supported_tlvs;
68
69   /*! number of supported tlv ids */
70   size_t supported_tlv_count;
71
72   /*! array of mandatory tlv ids */
73   const uint16_t *mandatory_tlvs;
74
75   /*! number of mandatory tlv ids */
76   size_t mandatory_tlv_count;
77
78   /*! array of tlvs that are allowed multiple times */
79   const uint16_t *duplicate_tlvs;
80
81   /*! number of tlvs that are allowed multiple times */
82   size_t duplicate_tlv_count;
83
84   /**
85    * Callback for processing radio data
86    * @param ext this dlep extension
87    * @param session current dlep session
88    * @return dlep error code
89    */
90   enum dlep_parser_error (*process_radio)(struct dlep_extension *ext, struct dlep_session *session);
91
92   /**
93    * Callback for processing router data
94    * @param ext this dlep extension
95    * @param session current dlep session
96    * @return dlep error code
97    */
98   enum dlep_parser_error (*process_router)(struct dlep_extension *ext, struct dlep_session *session);
99
100   /**
101    * Callback to add TLVs to the extended radio signal
102    * @param ext this dlep extension
103    * @param session current dlep session
104    * @param neigh neighbor used for this signal, might be NULL
105    * @return -1 if an error happened, 0 otherwise
106    */
107   int (*add_radio_tlvs)(struct dlep_extension *ext, struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh);
108
109   /**
110    * Callback to add TLVs to the extended router signal
111    * @param ext this dlep extension
112    * @param session current dlep session
113    * @param neigh neighbor used for this signal, might be NULL
114    * @return -1 if an error happened, 0 otherwise
115    */
116   int (*add_router_tlvs)(struct dlep_extension *ext, struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh);
117 };
118
119 /**
120  * one TLV used by a DLEP extension
121  */
122 struct dlep_extension_tlv {
123   /*! tlv id */
124   uint16_t id;
125
126   /*! minimal length of tlv value */
127   uint16_t length_min;
128
129   /*! maximal length of tlv value */
130   uint16_t length_max;
131 };
132
133 /**
134  * implementation of a DLEP signal.
135  *
136  * This is used for extensions that must be split
137  * into radio and router code. The dlep_extension_add_processing()
138  * function will add the implementation to the callbacks in
139  * dlep_extension_signal.
140  */
141 struct dlep_extension_implementation {
142   /*! extension id */
143   int32_t id;
144
145   /**
146    * Callback for data processing
147    * @param ext this dlep extension
148    * @param session current dlep session
149    * @return dlep error code
150    */
151   enum dlep_parser_error (*process)(struct dlep_extension *ext, struct dlep_session *session);
152
153   /**
154    * Callback to add TLVs to the extended signal
155    * @param ext this dlep extension
156    * @param session current dlep session
157    * @param neigh neighbor used for this signal, might be NULL
158    * @return -1 if an error happened, 0 otherwise
159    */
160   int (*add_tlvs)(struct dlep_extension *ext, struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh);
161 };
162
163 /**
164  * Defines an mapping between a layer2_neighbor element and
165  * a DLEP TLV
166  */
167 struct dlep_neighbor_mapping {
168   /*! dlep tlv id */
169   uint16_t dlep;
170
171   /*! binary length of tlv */
172   uint16_t length;
173
174   /*! layer2 neighbor id */
175   enum oonf_layer2_neighbor_index layer2;
176
177   /*! TLV is mandatory */
178   bool mandatory;
179
180   /*! default value for mandatory TLVs */
181   union oonf_layer2_value default_value;
182
183   /**
184    * callback to transform a TLV into layer2 data
185    * @param l2data layer2 data
186    * @param meta metadata description for data
187    * @param session dlep session
188    * @param tlv tlv id
189    * @return -1 if an error happened, 0 otherwise
190    */
191   int (*from_tlv)(struct oonf_layer2_data *l2data, const struct oonf_layer2_metadata *meta,
192     struct dlep_session *session, uint16_t tlv);
193
194   /**
195    * callback to transform layer2 data into a DLEP tlv
196    * @param writer dlep writer
197    * @param l2data layer2 data
198    * @param meta metadata description for data
199    * @param tlv tlv id
200    * @param length tlv length
201    * @return -1 if an error happened, 0 otherwise
202    */
203   int (*to_tlv)(struct dlep_writer *writer, struct oonf_layer2_data *l2data, const struct oonf_layer2_metadata *meta,
204     uint16_t tlv, uint16_t length);
205 };
206
207 /**
208  * Defines an mapping between a layer2_network element and
209  * a DLEP TLV
210  */
211 struct dlep_network_mapping {
212   /*! dlep tlv id */
213   uint16_t dlep;
214
215   /*! binary length of tlv */
216   uint16_t length;
217
218   /*! layer2 network index */
219   enum oonf_layer2_network_index layer2;
220
221   /*! TLV is mandatory */
222   bool mandatory;
223
224   /*! default value for mandatory TLVs */
225   union oonf_layer2_value default_value;
226
227   /**
228    * callback to transform a TLV into layer2 data
229    * @param l2data layer2 data
230    * @param meta metadata description for data
231    * @param session dlep session
232    * @param tlv tlv id
233    * @return -1 if an error happened, 0 otherwise
234    */
235   int (*from_tlv)(struct oonf_layer2_data *l2data, const struct oonf_layer2_metadata *meta,
236     struct dlep_session *session, uint16_t tlv);
237
238   /**
239    * callback to transform layer2 data into a DLEP tlv
240    * @param writer dlep writer
241    * @param l2data layer2 data
242    * @param meta metadata description for data
243    * @param tlv tlv id
244    * @param length tlv length
245    * @return -1 if an error happened, 0 otherwise
246    */
247   int (*to_tlv)(struct dlep_writer *writer, struct oonf_layer2_data *l2data, const struct oonf_layer2_metadata *meta,
248     uint16_t tlv, uint16_t length);
249 };
250
251 /**
252  * definition of a DLEP extension
253  */
254 struct dlep_extension {
255   /*! id of dlep extension, -1 for base protocol */
256   int id;
257
258   /*! name of extension for debugging purpose */
259   const char *name;
260
261   /*! array of dlep signals used by this extension */
262   struct dlep_extension_signal *signals;
263
264   /*! number of dlep signals used by this extension */
265   size_t signal_count;
266
267   /*! array of dlep tlvs used by this extension */
268   struct dlep_extension_tlv *tlvs;
269
270   /*! number of dlep tlvs used by this extension */
271   size_t tlv_count;
272
273   /**
274    * array of id mappings between DLEP tlvs
275    * and oonf-layer2 neighbor data
276    */
277   struct dlep_neighbor_mapping *neigh_mapping;
278
279   /*! number of id mappings for layer2 neighbor data */
280   size_t neigh_mapping_count;
281
282   /**
283    * array of id mappings between DLEP tlvs
284    * and oonf-layer2 network data
285    */
286   struct dlep_network_mapping *if_mapping;
287
288   /*! number of id mappings for layer2 network data */
289   size_t if_mapping_count;
290
291   /**
292    * Callback to initialize a new radio session
293    * @param session dlep session
294    */
295   void (*cb_session_init_radio)(struct dlep_session *session);
296
297   /**
298    * Callback to initialize a new router session
299    * @param session dlep session
300    */
301   void (*cb_session_init_router)(struct dlep_session *session);
302
303   /**
304    * Callback to apply new interface sessions to a new radio session
305    * @param session dlep session
306    */
307   void (*cb_session_apply_radio)(struct dlep_session *session);
308
309   /**
310    * Callback to apply new interface sessions to a new router session
311    * @param session dlep session
312    */
313   void (*cb_session_apply_router)(struct dlep_session *session);
314
315   /**
316    * Callback to deactivate an extension for a radio session
317    * @param session dlep session
318    */
319   void (*cb_session_deactivate_radio)(struct dlep_session *session);
320
321   /**
322    * Callback to deactivate an extension for a router session
323    * @param session dlep session
324    */
325   void (*cb_session_deactivate_router)(struct dlep_session *session);
326
327   /**
328    * Callback to cleanup all resources of a radio session
329    * @param session dlep session
330    */
331   void (*cb_session_cleanup_radio)(struct dlep_session *session);
332
333   /**
334    * Callback to cleanup all resources of a router session
335    * @param session dlep session
336    */
337   void (*cb_session_cleanup_router)(struct dlep_session *session);
338
339   /*! node for global tree of extensions */
340   struct avl_node _node;
341 };
342
343 EXPORT void dlep_extension_init(void);
344 EXPORT void dlep_extension_cleanup(void);
345
346 EXPORT void dlep_extension_add(struct dlep_extension *);
347 EXPORT struct avl_tree *dlep_extension_get_tree(void);
348 EXPORT void dlep_extension_add_processing(
349   struct dlep_extension *, bool radio, struct dlep_extension_implementation *proc, size_t proc_count);
350 EXPORT const uint16_t *dlep_extension_get_ids(uint16_t *length);
351
352 EXPORT int dlep_extension_get_l2_neighbor_key(struct oonf_layer2_neigh_key *key, struct dlep_session *session);
353 EXPORT struct oonf_layer2_neigh *dlep_extension_get_l2_neighbor(struct dlep_session *session);
354
355 EXPORT enum dlep_parser_error dlep_extension_router_process_session_init_ack(struct dlep_extension *, struct dlep_session *session);
356 EXPORT enum dlep_parser_error dlep_extension_router_process_session_update(struct dlep_extension *, struct dlep_session *session);
357 EXPORT enum dlep_parser_error dlep_extension_router_process_destination(struct dlep_extension *, struct dlep_session *session);
358 EXPORT int dlep_extension_radio_write_session_init_ack(
359   struct dlep_extension *ext, struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh);
360 EXPORT int dlep_extension_radio_write_session_update(
361   struct dlep_extension *ext, struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh);
362 EXPORT int dlep_extension_radio_write_destination(
363   struct dlep_extension *ext, struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh);
364
365 /**
366  * @param id dlep extension id
367  * @return dlep extension, NULL if not found
368  */
369 static INLINE struct dlep_extension *
370 dlep_extension_get(int32_t id) {
371   struct dlep_extension *ext;
372   return avl_find_element(dlep_extension_get_tree(), &id, ext, _node);
373 }
374
375 #endif /* _DLEP_EXTENSION_H_ */