Rename "subsystems" directory to "base"
[oonf.git] / src / olsrv2 / olsrv2 / olsrv2_originator.c
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 #include <oonf/libcommon/avl.h>
47 #include <oonf/libcommon/avl_comp.h>
48 #include <oonf/oonf.h>
49 #include <oonf/libcommon/netaddr.h>
50 #include <oonf/libcommon/netaddr_acl.h>
51 #include <oonf/libcore/oonf_logging.h>
52 #include <oonf/base/oonf_class.h>
53 #include <oonf/base/oonf_timer.h>
54 #include <oonf/base/os_interface.h>
55
56 #include <oonf/nhdp/nhdp/nhdp.h>
57
58 #include <oonf/olsrv2/olsrv2/olsrv2.h>
59 #include <oonf/olsrv2/olsrv2/olsrv2_originator.h>
60
61 /* prototypes */
62 static struct olsrv2_originator_set_entry *_remember_removed_originator(struct netaddr *originator, uint64_t vtime);
63 static void _set_originator(int af_type, struct netaddr *setting, const struct netaddr *new_originator);
64 static void _cb_originator_entry_vtime(struct oonf_timer_instance *);
65 static void _remove_originator_entry(struct olsrv2_originator_set_entry *entry);
66
67 /* originator set class and timer */
68 static struct oonf_class _originator_entry_class = {
69   .name = "OLSRV2 originator set",
70   .size = sizeof(struct olsrv2_originator_set_entry),
71 };
72
73 static struct oonf_timer_class _originator_entry_timer = {
74   .name = "OLSRV2 originator set vtime",
75   .callback = _cb_originator_entry_vtime,
76 };
77
78 /* global tree of originator set entries */
79 static struct avl_tree _originator_set_tree;
80
81 /* current originators */
82 static struct netaddr _originator_v4, _originator_v6;
83
84 /**
85  * Initialize olsrv2 originator set
86  */
87 void
88 olsrv2_originator_init(void) {
89   /* initialize class and timer */
90   oonf_class_add(&_originator_entry_class);
91   oonf_timer_add(&_originator_entry_timer);
92
93   /* initialize global originator tree */
94   avl_init(&_originator_set_tree, avl_comp_netaddr, false);
95 }
96
97 /**
98  * Cleanup all resources allocated by orignator set
99  */
100 void
101 olsrv2_originator_cleanup(void) {
102   struct olsrv2_originator_set_entry *entry, *e_it;
103
104   /* remove all originator entries */
105   avl_for_each_element_safe(&_originator_set_tree, entry, _node, e_it) {
106     _remove_originator_entry(entry);
107   }
108
109   /* remove timer and class */
110   oonf_timer_remove(&_originator_entry_timer);
111   oonf_class_remove(&_originator_entry_class);
112 }
113
114 /**
115  * @param af_type address type of originator
116  * @return current originator address of specified type
117  */
118 const struct netaddr *
119 olsrv2_originator_get(int af_type) {
120   if (af_type == AF_INET) {
121     return &_originator_v4;
122   }
123   else if (af_type == AF_INET6) {
124     return &_originator_v6;
125   }
126   return NULL;
127 }
128
129 /**
130  * @param addr network address
131  * @return true if address is (or was) the local originator
132  */
133 bool
134 olsrv2_originator_is_local(const struct netaddr *addr) {
135   if (netaddr_cmp(&_originator_v4, addr) == 0) {
136     return true;
137   }
138   if (netaddr_cmp(&_originator_v6, addr) == 0) {
139     return true;
140   }
141   return olsrv2_originator_get_entry(addr) != NULL;
142 }
143
144 /**
145  * Sets the originator address to a new value.
146  * Parameter af_type is necessary for the case when both
147  * current and new setting are AF_UNSPEC.
148  *
149  * @param originator new originator
150  */
151 void
152 olsrv2_originator_set(const struct netaddr *originator) {
153   if (netaddr_get_address_family(originator) == AF_INET) {
154     _set_originator(AF_INET, &_originator_v4, originator);
155   }
156   else if (netaddr_get_address_family(originator) == AF_INET6) {
157     _set_originator(AF_INET6, &_originator_v6, originator);
158   }
159 }
160
161 /**
162  * Get tree of old originator IPs
163  * @return originator tree
164  */
165 struct avl_tree *
166 olsrv2_originator_get_tree(void) {
167   return &_originator_set_tree;
168 }
169
170 /**
171  * Add a new entry to the olsrv2 originator set
172  * @param originator originator address
173  * @param vtime validity time of entry
174  * @return pointer to originator set entry, NULL if out of memory
175  */
176 static struct olsrv2_originator_set_entry *
177 _remember_removed_originator(struct netaddr *originator, uint64_t vtime) {
178   struct olsrv2_originator_set_entry *entry;
179
180   entry = olsrv2_originator_get_entry(originator);
181   if (entry == NULL) {
182     entry = oonf_class_malloc(&_originator_entry_class);
183     if (entry == NULL) {
184       /* out of memory */
185       return NULL;
186     }
187
188     /* copy key and append to tree */
189     memcpy(&entry->originator, originator, sizeof(*originator));
190     entry->_node.key = &entry->originator;
191     avl_insert(&_originator_set_tree, &entry->_node);
192
193     /* initialize timer */
194     entry->_vtime.class = &_originator_entry_timer;
195   }
196
197   /* reset validity time */
198   oonf_timer_set(&entry->_vtime, vtime);
199
200   return entry;
201 }
202
203 /**
204  * Sets the originator address to a new value.
205  * Parameter af_type is necessary for the case when both
206  * current and new setting are AF_UNSPEC.
207  *
208  * @param af_type address family type of the originator
209  *   (AF_INET or AF_INET6)
210  * @param setting pointer to the storage of the originator
211  * @param new_originator new originator
212  */
213 static void
214 _set_originator(int af_type, struct netaddr *setting, const struct netaddr *new_originator) {
215   struct olsrv2_originator_set_entry *entry;
216
217   if (netaddr_get_address_family(setting) != AF_UNSPEC) {
218     /* add old originator to originator set */
219     _remember_removed_originator(setting, olsrv2_get_old_originator_validity());
220   }
221
222   memcpy(setting, new_originator, sizeof(*setting));
223
224   /* remove new_originator originator from set */
225   entry = olsrv2_originator_get_entry(new_originator);
226   if (entry) {
227     _remove_originator_entry(entry);
228   }
229
230   /* update NHDP originator */
231   if (netaddr_get_address_family(new_originator) != AF_UNSPEC) {
232     nhdp_set_originator(new_originator);
233   }
234   else {
235     nhdp_reset_originator(af_type);
236   }
237 }
238
239 /**
240  * Callback fired when originator set entry must be removed
241  * @param ptr timer instance that fired
242  */
243 static void
244 _cb_originator_entry_vtime(struct oonf_timer_instance *ptr) {
245   struct olsrv2_originator_set_entry *entry;
246
247   entry = container_of(ptr, struct olsrv2_originator_set_entry, _vtime);
248   _remove_originator_entry(entry);
249 }
250
251 static void
252 _remove_originator_entry(struct olsrv2_originator_set_entry *entry) {
253   oonf_timer_stop(&entry->_vtime);
254   avl_remove(&_originator_set_tree, &entry->_node);
255
256   oonf_class_free(&_originator_entry_class, entry);
257 }