b0bab21430e52b206306f97d3eb705694cd11dea
[oonf.git] / include / oonf / subsystems / oonf_rfc5444.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 OONF_RFC5444_H_
47 #define OONF_RFC5444_H_
48
49 #include <oonf/libcommon/avl.h>
50 #include <oonf/oonf.h>
51 #include <oonf/libcommon/netaddr.h>
52 #include <oonf/subsystems/oonf_duplicate_set.h>
53 #include <oonf/subsystems/oonf_packet_socket.h>
54 #include <oonf/subsystems/oonf_timer.h>
55 #include <oonf/librfc5444/rfc5444.h>
56 #include <oonf/librfc5444/rfc5444_context.h>
57 #include <oonf/librfc5444/rfc5444_iana.h>
58 #include <oonf/librfc5444/rfc5444_reader.h>
59 #include <oonf/librfc5444/rfc5444_writer.h>
60
61 /*! subsystem identifier */
62 #define OONF_RFC5444_SUBSYSTEM "rfc5444"
63
64 /**
65  * suggested priorities for RFC5444 readers
66  */
67 enum
68 {
69   RFC5444_VALIDATOR_PRIORITY = -256,
70   RFC5444_MAIN_PARSER_PRIORITY = 0,
71   RFC5444_LQ_PARSER_PRIORITY = 64,
72   RFC5444_PLUGIN_PARSER_PRIORITY = 256,
73 };
74
75 /*! Configuration section for global mesh settings */
76 #define CFG_RFC5444_SECTION "mesh"
77
78 enum
79 {
80   /*! Maximum buffer size for address TLVs before splitting */
81   RFC5444_ADDRTLV_BUFFER = 65536,
82 };
83
84 /*! Interface name for unicast targets */
85 #define RFC5444_UNICAST_INTERFACE OS_INTERFACE_ANY
86
87 /*! memory class for rfc5444 protocol */
88 #define RFC5444_CLASS_PROTOCOL "RFC5444 protocol"
89
90 /*! memory class for rfc5444 interface */
91 #define RFC5444_CLASS_INTERFACE "RFC5444 interface"
92
93 /*! memory class for rfc5444 target */
94 #define RFC5444_CLASS_TARGET "RFC5444 target"
95
96 struct oonf_rfc5444_target;
97
98 /**
99  * Parameters regarding currently parsed RFC5444 packet
100  */
101 struct oonf_rfc5444_input_parameters {
102   /*! source address of currently parsed RFC5444 packet */
103   struct netaddr *src_address;
104
105   /*! source address and port of currently parsed RFC5444 packet */
106   union netaddr_socket *src_socket;
107
108   /*! interface of currently parsed RFC5444 packet */
109   struct oonf_rfc5444_interface *interface;
110
111   /*! true if currently parsed RFC5444 packet was multicast */
112   bool is_multicast;
113 };
114 /**
115  * Representation of a rfc5444 based protocol
116  */
117 struct oonf_rfc5444_protocol {
118   /*! name of the protocol */
119   char name[32];
120
121   /*! port number of the protocol */
122   uint16_t port;
123
124   /**
125    * true if the local port must be the protocol port,
126    * false if it may be random
127    */
128   bool fixed_local_port;
129
130   /*! IP protocol number for raw IP communication */
131   int ip_proto;
132
133   /*! parameters of currently parsed incoming packet */
134   struct oonf_rfc5444_input_parameters input;
135
136   /*! RFC5444 reader for this protocol instance */
137   struct rfc5444_reader reader;
138
139   /*! RFC5444 writer for this protocol instance */
140   struct rfc5444_writer writer;
141
142   /*! processed set as defined in OLSRv2 */
143   struct oonf_duplicate_set processed_set;
144
145   /*! forwarded set as defined in OLSRv2 */
146   struct oonf_duplicate_set forwarded_set;
147
148   /*! node for tree of protocols */
149   struct avl_node _node;
150
151   /*! tree of interfaces for this protocol */
152   struct avl_tree _interface_tree;
153
154   /*! reference count of this protocol */
155   int _refcount;
156
157   /*! number of users who need a packet sequence number for all packets */
158   int _pktseqno_refcount;
159
160   /*! next protocol message sequence number */
161   uint16_t _msg_seqno;
162
163   /*! message buffer for protocol */
164   uint8_t _msg_buffer[RFC5444_MAX_MESSAGE_SIZE];
165
166   /*! buffer for addresstlvs before splitting the message */
167   uint8_t _addrtlv_buffer[RFC5444_ADDRTLV_BUFFER];
168 };
169
170 /**
171  * Representation of a rfc5444 interface of a protocol
172  */
173 struct oonf_rfc5444_interface {
174   /*! name of interface */
175   char name[IF_NAMESIZE];
176
177   /*! backpointer to protocol */
178   struct oonf_rfc5444_protocol *protocol;
179
180   /*! Node for tree of interfaces in protocol */
181   struct avl_node _node;
182
183   /*! tree of unicast targets */
184   struct avl_tree _target_tree;
185
186   /*! tree of interface event listeners of this interface */
187   struct list_entity _listener;
188
189   /*! managed socket for this interface */
190   struct oonf_packet_managed _socket;
191
192   /*! current socket configuration of this interface */
193   struct oonf_packet_managed_config _socket_config;
194
195   /*! pointer to ipv4 multicast targets for this interface */
196   struct oonf_rfc5444_target *multicast4;
197
198   /*! pointer to ipv6 multicast targets for this interface */
199   struct oonf_rfc5444_target *multicast6;
200
201   /*! interval the multiplexer will wait until it generates a packet */
202   uint64_t aggregation_interval;
203
204   /*!
205    * value to overwrite configured aggregation interval,
206    * 0 to use configured value
207    */
208   uint64_t overwrite_aggregation_interval;
209
210   /*! number of users of this interface */
211   int _refcount;
212 };
213
214 /**
215  * Represents a listener to the interface events of a rfc5444 interface
216  */
217 struct oonf_rfc5444_interface_listener {
218   /**
219    * Callback to signal a change of the RFC5444 interface
220    * @param l this interface listener
221    * @param changed true if a socket had to be reconfigured
222    */
223   void (*cb_interface_changed)(struct oonf_rfc5444_interface_listener *l, bool changed);
224
225   /*! backpointer to rfc5444 interface */
226   struct oonf_rfc5444_interface *interface;
227
228   /*! node for list of listeners of an interface */
229   struct list_entity _node;
230 };
231
232 /**
233  * Represents a target (destination IP) of a rfc5444 interface
234  */
235 struct oonf_rfc5444_target {
236   /*! rfc5444 API representation of the target */
237   struct rfc5444_writer_target rfc5444_target;
238
239   /*! destination IP */
240   struct netaddr dst;
241
242   /*! backpointer to interface */
243   struct oonf_rfc5444_interface *interface;
244
245   /*! node for tree of targets for unicast interfaces */
246   struct avl_node _node;
247
248   /*! timer for message aggregation on interface */
249   struct oonf_timer_instance _aggregation;
250
251   /*! number of users of this target */
252   int _refcount;
253
254   /*! number of users requesting a packet sequence number for this target */
255   int _pktseqno_refcount;
256
257   /*! last packet sequence number used for this target */
258   uint16_t _pktseqno;
259
260   /*! packet output buffer for target */
261   uint8_t _packet_buffer[RFC5444_MAX_PACKET_SIZE];
262 };
263
264 EXPORT struct oonf_rfc5444_protocol *oonf_rfc5444_add_protocol(const char *name, bool fixed_local_port);
265 EXPORT void oonf_rfc5444_remove_protocol(struct oonf_rfc5444_protocol *);
266 EXPORT void oonf_rfc5444_reconfigure_protocol(struct oonf_rfc5444_protocol *, uint16_t port, int ip_proto);
267 EXPORT struct oonf_rfc5444_protocol *oonf_rfc5444_get_default_protocol(void);
268
269 EXPORT struct oonf_rfc5444_interface *oonf_rfc5444_add_interface(
270   struct oonf_rfc5444_protocol *protocol, struct oonf_rfc5444_interface_listener *, const char *name);
271 EXPORT void oonf_rfc5444_remove_interface(struct oonf_rfc5444_interface *, struct oonf_rfc5444_interface_listener *);
272 EXPORT void oonf_rfc5444_reconfigure_interface(
273   struct oonf_rfc5444_interface *interf, struct oonf_packet_managed_config *config);
274 EXPORT struct oonf_rfc5444_target *oonf_rfc5444_add_target(
275   struct oonf_rfc5444_interface *interface, struct netaddr *dst);
276 EXPORT void oonf_rfc5444_remove_target(struct oonf_rfc5444_target *target);
277 EXPORT void oonf_rfc5444_send_target_data(struct oonf_rfc5444_target *target, const void *ptr, size_t len);
278 EXPORT void oonf_rfc5444_send_interface_data(
279   struct oonf_rfc5444_interface *interf, const struct netaddr *dst, const void *ptr, size_t len);
280
281 EXPORT uint64_t oonf_rfc5444_interface_set_aggregation(struct oonf_rfc5444_interface *interf, uint64_t aggregation);
282
283 EXPORT const union netaddr_socket *oonf_rfc5444_interface_get_local_socket(
284   struct oonf_rfc5444_interface *rfc5444_if, int af_type);
285 EXPORT const union netaddr_socket *oonf_rfc5444_target_get_local_socket(struct oonf_rfc5444_target *target);
286
287 EXPORT enum rfc5444_result oonf_rfc5444_send_if(struct oonf_rfc5444_target *, uint8_t msgid);
288 EXPORT enum rfc5444_result oonf_rfc5444_send_all(
289   struct oonf_rfc5444_protocol *protocol, uint8_t msgid, uint8_t addr_len, rfc5444_writer_targetselector useIf);
290
291 EXPORT void oonf_rfc5444_block_output(bool block);
292
293 /**
294  * @param protocol RFC5444 protocol
295  * @param name interface name
296  * @return RFC5444 interface, NULL if not found
297  */
298 static INLINE struct oonf_rfc5444_interface *
299 oonf_rfc5444_get_interface(struct oonf_rfc5444_protocol *protocol, const char *name) {
300   struct oonf_rfc5444_interface *interf;
301   return avl_find_element(&protocol->_interface_tree, name, interf, _node);
302 }
303
304 /**
305  * Flush a target and send out the message/packet immediately
306  * @param target rfc5444 target
307  * @param force true to force an empty packet if necessary, false will only
308  *   flush if a message is in the buffer
309  */
310 static INLINE void
311 oonf_rfc5444_flush_target(struct oonf_rfc5444_target *target, bool force) {
312   rfc5444_writer_flush(&target->interface->protocol->writer, &target->rfc5444_target, force);
313 }
314
315 /**
316  * @param writer pointer to rfc5444 writer
317  * @return pointer to rfc5444 target used by message
318  */
319 static INLINE struct oonf_rfc5444_target *
320 oonf_rfc5444_get_target_from_writer(struct rfc5444_writer *writer) {
321   return container_of_if_notnull(writer->msg_target, struct oonf_rfc5444_target, rfc5444_target);
322 }
323
324 /**
325  * @param target rfc5444 writer target
326  * @return pointer to oonf_rfc5444 target
327  */
328 static INLINE struct oonf_rfc5444_target *
329 oonf_rfc5444_get_target_from_rfc5444_target(struct rfc5444_writer_target *target) {
330   return container_of(target, struct oonf_rfc5444_target, rfc5444_target);
331 }
332
333 /**
334  * @param interf pointer to rfc5444 interface
335  * @return pointer to olsr interface
336  */
337 static INLINE struct os_interface_listener *
338 oonf_rfc5444_get_core_if_listener(struct oonf_rfc5444_interface *interf) {
339   return &interf->_socket._if_listener;
340 }
341
342 /**
343  * @param interface pointer to rfc5444 interface
344  * @param af_type address family
345  * @return true if the target (address family type) socket is active
346  */
347 static INLINE bool
348 oonf_rfc5444_is_interface_active(struct oonf_rfc5444_interface *interface, int af_type) {
349   return oonf_packet_managed_is_active(&interface->_socket, af_type);
350 }
351
352 /**
353  * @param target pointer to rfc5444 target
354  * @return true if the target (address family type) socket is active
355  */
356 static INLINE bool
357 oonf_rfc5444_is_target_active(struct oonf_rfc5444_target *target) {
358   return target != NULL &&
359          oonf_packet_managed_is_active(&target->interface->_socket, netaddr_get_address_family(&target->dst));
360 }
361
362 /**
363  * Request a protocol wide packet sequence number
364  * @param protocol pointer to rfc5444 protocol instance
365  */
366 static INLINE void
367 oonf_rfc5444_add_protocol_pktseqno(struct oonf_rfc5444_protocol *protocol) {
368   protocol->_pktseqno_refcount++;
369 }
370
371 /**
372  * Release the request for a protocol wide packet sequence number
373  * @param protocol pointer to rfc5444 protocol instance
374  */
375 static INLINE void
376 oonf_rfc5444_remove_protocol_pktseqno(struct oonf_rfc5444_protocol *protocol) {
377   if (protocol->_pktseqno_refcount > 0) {
378     protocol->_pktseqno_refcount--;
379   }
380 }
381
382 /**
383  * Request packet sequence number for a target
384  * @param target rfc5444 target
385  */
386 static INLINE void
387 oonf_rfc5444_add_target_pktseqno(struct oonf_rfc5444_target *target) {
388   target->_pktseqno_refcount++;
389 }
390
391 /**
392  * Release the request for a packet sequence number for a target
393  * @param target rfc5444 target
394  */
395 static INLINE void
396 oonf_rfc5444_remove_target_pktseqno(struct oonf_rfc5444_target *target) {
397   if (target->_pktseqno_refcount > 0) {
398     target->_pktseqno_refcount--;
399   }
400 }
401
402 /**
403  * @param target pointer to rfc5444 target instance
404  * @return last used packet sequence number on this target
405  */
406 static INLINE uint16_t
407 oonf_rfc5444_get_last_packet_seqno(struct oonf_rfc5444_target *target) {
408   return target->_pktseqno;
409 }
410
411 /**
412  * Generates a new message sequence number for a protocol.
413  * @param protocol pointer to rfc5444 protocol instance
414  * @return new message sequence number
415  */
416 static INLINE uint16_t
417 oonf_rfc5444_get_next_message_seqno(struct oonf_rfc5444_protocol *protocol) {
418   protocol->_msg_seqno++;
419
420   return protocol->_msg_seqno;
421 }
422
423 #endif /* OONF_RFC5444_H_ */