Remove the olsr-specific duplicated types
[olsrd.git] / src / hna_set.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in
14  *   the documentation and/or other materials provided with the
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include "hna_set.h"
42 #include "ipcalc.h"
43 #include "defs.h"
44 #include "parser.h"
45 #include "olsr.h"
46 #include "scheduler.h"
47 #include "net_olsr.h"
48 #include "tc_set.h"
49
50 /* Some cookies for stats keeping */
51 struct olsr_cookie_info *hna_net_timer_cookie = NULL;
52 struct olsr_cookie_info *hna_net_mem_cookie = NULL;
53
54 /**
55  * Initialize the HNA set
56  */
57 void
58 olsr_init_hna_set(void)
59 {
60   OLSR_PRINTF(5, "HNA: init\n");
61
62   hna_net_timer_cookie =
63     olsr_alloc_cookie("HNA Network", OLSR_COOKIE_TYPE_TIMER);
64
65   hna_net_mem_cookie =
66     olsr_alloc_cookie("hna_net", OLSR_COOKIE_TYPE_MEMORY);
67   olsr_cookie_set_memory_size(hna_net_mem_cookie, sizeof(struct hna_net));
68 }
69
70 /**
71  * Lookup a network entry in the HNA subtree.
72  *
73  * @param tc the HNA hookup point
74  * @param prefic the prefix to look for
75  *
76  * @return the localized entry or NULL of not found
77  */
78 static struct hna_net *
79 olsr_lookup_hna_net(struct tc_entry *tc, const struct olsr_ip_prefix *prefix)
80 {
81   return (hna_tc_tree2hna(avl_find(&tc->hna_tree, prefix)));
82 }
83
84 /**
85  * Adds a network entry to a HNA gateway.
86  *
87  * @param tc the gateway entry to add the network to
88  * @param net the nework prefix to add
89  * @param prefixlen the prefix length
90  *
91  * @return the newly created entry
92  */
93 static struct hna_net *
94 olsr_add_hna_net(struct tc_entry *tc, const struct olsr_ip_prefix *prefix)
95 {
96   /* Add the net */
97   struct hna_net *new_net = olsr_cookie_malloc(hna_net_mem_cookie);
98
99   /* Fill struct */
100   new_net->hna_prefix = *prefix;
101
102   /* Set backpointer */
103   new_net->hna_tc = tc;
104   olsr_lock_tc_entry(tc);
105
106   /*
107    * Insert into the per-tc hna subtree.
108    */
109   new_net->hna_tc_node.key = &new_net->hna_prefix;
110   avl_insert(&tc->hna_tree, &new_net->hna_tc_node, AVL_DUP_NO);
111
112   return new_net;
113 }
114
115 /**
116  * Delete a single HNA network.
117  *
118  * @param hna_net the hna_net to delete.
119  */
120 static void
121 olsr_delete_hna_net(struct hna_net *hna_net)
122 {
123   struct tc_entry *tc = hna_net->hna_tc;
124
125   /*
126    * Delete the rt_path for the hna_net.
127    */
128   olsr_delete_routing_table(&hna_net->hna_prefix.prefix,
129                             hna_net->hna_prefix.prefix_len,
130                             &tc->addr);
131
132   /*
133    * Remove from the per-tc tree.
134    */
135   avl_delete(&tc->hna_tree, &hna_net->hna_tc_node);
136
137   /*
138    * Unlock and free.
139    */
140   olsr_unlock_tc_entry(tc);
141   olsr_cookie_free(hna_net_mem_cookie, hna_net);
142 }
143
144 /**
145  * Callback for the hna_net timer.
146  */
147 static void
148 olsr_expire_hna_net_entry(void *context)
149 {
150   struct hna_net *hna_net = context;
151 #ifdef DEBUG
152   struct ipaddr_str buf;
153   struct ipprefix_str prefixstr;
154
155   OLSR_PRINTF(5, "HNA: timeout %s via hna-gw %s\n",
156               olsr_ip_prefix_to_string(&prefixstr, &hna_net->hna_prefix),
157               olsr_ip_to_string(&buf, &hna_net->hna_tc->addr));
158 #endif
159
160   hna_net->hna_net_timer = NULL; /* be pedandic */
161
162   olsr_delete_hna_net(hna_net);
163 }
164
165 /**
166  * Update a HNA entry. If it does not exist it
167  * is created.
168  * This is the only function that should be called
169  * from outside concerning creation of HNA entries.
170  *
171  *@param gw address of the gateway
172  *@param net address of the network
173  *@param mask the netmask
174  *@param vtime the validitytime of the entry
175  *
176  *@return nada
177  */
178 void
179 olsr_update_hna_entry(const union olsr_ip_addr *gw,
180                       const struct olsr_ip_prefix *prefix,
181                       olsr_reltime vtime)
182 {
183   struct tc_entry *tc = olsr_locate_tc_entry(gw);
184   struct hna_net *net_entry = olsr_lookup_hna_net(tc, prefix);
185
186   if (net_entry == NULL) {
187     /* Need to add the net */
188     net_entry = olsr_add_hna_net(tc, prefix);
189     changes_hna = true;
190   }
191
192   /*
193    * Add the rt_path for the entry.
194    */
195   olsr_insert_routing_table(&net_entry->hna_prefix.prefix,
196                             net_entry->hna_prefix.prefix_len,
197                             &tc->addr,
198                             OLSR_RT_ORIGIN_HNA);
199
200   /*
201    * Start, or refresh the timer, whatever is appropriate.
202    */
203   olsr_set_timer(&net_entry->hna_net_timer, vtime,
204                  OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT,
205                  &olsr_expire_hna_net_entry, net_entry,
206                  hna_net_timer_cookie->ci_id);
207 }
208
209 /**
210  * Print all HNA entries.
211  *
212  *@return nada
213  */
214 void
215 olsr_print_hna_set(void)
216 {
217   /* The whole function doesn't do anything else. */
218 #ifndef NODEBUG
219   struct tc_entry *tc;
220
221   OLSR_PRINTF(1,
222               "\n--- %s ------------------------------------------------- HNA\n\n",
223               olsr_wallclock_string());
224
225   OLSR_FOR_ALL_TC_ENTRIES(tc) {
226     struct ipaddr_str buf;
227     struct hna_net *hna_net;
228     OLSR_PRINTF(1, "HNA-gw %s: ", olsr_ip_to_string(&buf, &tc->addr));
229     OLSR_FOR_ALL_TC_HNA_ENTRIES(tc, hna_net) {
230       struct ipprefix_str prefixstr;
231       OLSR_PRINTF(1, "%-27s", olsr_ip_prefix_to_string(&prefixstr, &hna_net->hna_prefix));
232     } OLSR_FOR_ALL_TC_HNA_ENTRIES_END(tc, hna_net);
233     OLSR_PRINTF(1, "\n");
234   } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
235 #endif
236 }
237
238 /**
239  * Process incoming HNA message.
240  * Forwards the message if that is to be done.
241  */
242 bool
243 olsr_input_hna(union olsr_message *msg,
244                struct interface *in_if __attribute__((unused)),
245                union olsr_ip_addr *from_addr)
246 {
247   struct olsrmsg_hdr msg_hdr;
248   struct olsr_ip_prefix prefix;
249   struct ipaddr_str buf;
250   const uint8_t *curr, *curr_end;
251   int hnasize;
252
253   if (!(curr = olsr_parse_msg_hdr(msg, &msg_hdr))) {
254     return false;
255   }
256
257   /* We are only interested in HNA message types. */
258   if (msg_hdr.type != HNA_MESSAGE) {
259     return false;
260   }
261
262   hnasize = msg_hdr.size - (olsr_cnf->ip_version == AF_INET ?
263                             offsetof(struct olsrmsg, message) :
264                             offsetof(struct olsrmsg6, message));
265   if (hnasize < 0) {
266     OLSR_PRINTF(0, "HNA message size %d too small (at least %lu)!\n",
267                 msg_hdr.size,
268                 (unsigned long)(olsr_cnf->ip_version == AF_INET ?
269                                 offsetof(struct olsrmsg, message) :
270                                 offsetof(struct olsrmsg6, message)));
271     return false;
272   }
273
274   if ((hnasize % (2 * olsr_cnf->ipsize)) != 0) {
275     OLSR_PRINTF(0, "HNA message size %d illegal!\n", msg_hdr.size);
276     return false;
277   }
278
279   /*
280    * If the sender interface (NB: not originator) of this message
281    * is not in the symmetric 1-hop neighborhood of this node, the
282    * message MUST be discarded.
283    */
284   if (check_neighbor_link(from_addr) != SYM_LINK) {
285     OLSR_PRINTF(2, "Received HNA from NON SYM neighbor %s\n",
286                 olsr_ip_to_string(&buf, from_addr));
287     return false;
288   }
289
290   OLSR_PRINTF(1, "Processing HNA from %s, seq 0x%04x\n",
291               olsr_ip_to_string(&buf, &msg_hdr.originator), msg_hdr.seqno);
292
293   /*
294    * Now walk the list of HNA advertisements.
295    */
296   curr_end = (const uint8_t *)msg + msg_hdr.size;
297   while (curr < curr_end) {
298
299     pkt_get_ipaddress(&curr, &prefix.prefix);
300     pkt_get_prefixlen(&curr, &prefix.prefix_len);
301
302     if (!ip_prefix_list_find(olsr_cnf->hna_entries, &prefix.prefix,
303                              prefix.prefix_len)) {
304       /*
305        * Only update if it's not from us.
306        */
307       olsr_update_hna_entry(&msg_hdr.originator, &prefix, msg_hdr.vtime);
308     }
309   }
310   /* Forward the message */
311   return true;
312 }
313
314 /*
315  * Local Variables:
316  * c-basic-offset: 2
317  * indent-tabs-mode: nil
318  * End:
319  */