* applied rt-refactoring-6.diff from Hannes Gredler <hannes@gredler.at>
[olsrd.git] / src / hna_set.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(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  * $Id: hna_set.c,v 1.21 2007/09/05 16:11:10 bernd67 Exp $
40  */
41
42 #include "defs.h"
43 #include "olsr.h"
44 #include "scheduler.h"
45
46
47 struct hna_entry hna_set[HASHSIZE];
48 size_t netmask_size;
49
50
51 /**
52  *Initialize the HNA set
53  */
54 int
55 olsr_init_hna_set(void)
56 {
57
58   int idx;
59
60   if(olsr_cnf->ip_version == AF_INET)
61     {
62       netmask_size = sizeof(olsr_u32_t);
63     }
64   else
65     {
66       netmask_size = sizeof(olsr_u16_t);
67     }
68
69   /* Since the holdingtime is assumed to be rather large for 
70    * HNA entries, the timeoutfunction is only ran once every second
71    */
72   olsr_register_scheduler_event(&olsr_time_out_hna_set, NULL, 1, 0, NULL);
73
74   for(idx=0;idx<HASHSIZE;idx++)
75     {
76       hna_set[idx].next = &hna_set[idx];
77       hna_set[idx].prev = &hna_set[idx];
78     }
79
80   return 1;
81 }
82
83 int
84 olsr_get_hna_prefix_len(struct hna_net *hna)
85 {
86   if (olsr_cnf->ip_version == AF_INET) {
87     return olsr_netmask_to_prefix((union olsr_ip_addr *)&hna->A_netmask.v4);
88   } else {
89     return hna->A_netmask.v6;
90   }
91 }
92
93
94 /**
95  *Lookup a network entry in a networkentry list
96  *
97  *@param nets the network list to look in
98  *@param net the network to look for
99  *@param mask the netmask to look for
100  *
101  *@return the localted entry or NULL of not found
102  */
103 struct hna_net *
104 olsr_lookup_hna_net(struct hna_net *nets, union olsr_ip_addr *net, union hna_netmask *mask)
105 {
106   struct hna_net *tmp_net;
107
108
109   /* Loop trough entrys */
110   for(tmp_net = nets->next;
111       tmp_net != nets;
112       tmp_net = tmp_net->next)
113     { 
114       if(COMP_IP(&tmp_net->A_network_addr, net) &&
115          (memcmp(&tmp_net->A_netmask, mask, netmask_size) == 0))
116         return tmp_net;
117     }
118   
119   /* Not found */
120   return NULL;
121 }
122
123
124
125
126 /**
127  *Lookup a gateway entry
128  *
129  *@param gw the address of the gateway
130  *
131  *@return the located entry or NULL if not found
132  */
133 struct hna_entry *
134 olsr_lookup_hna_gw(union olsr_ip_addr *gw)
135 {
136   struct hna_entry *tmp_hna;
137   olsr_u32_t hash;
138
139   //OLSR_PRINTF(5, "TC: lookup entry\n");
140
141   hash = olsr_hashing(gw);
142   
143   /* Check for registered entry */
144   for(tmp_hna = hna_set[hash].next;
145       tmp_hna != &hna_set[hash];
146       tmp_hna = tmp_hna->next)
147     {
148       if(COMP_IP(&tmp_hna->A_gateway_addr, gw))
149         return tmp_hna;
150     }
151   
152   /* Not found */
153   return NULL;
154 }
155
156
157
158 /**
159  *Add a gatewayentry to the HNA set
160  *
161  *@param addr the address of the gateway
162  *
163  *@return the created entry
164  */
165 struct hna_entry *
166 olsr_add_hna_entry(union olsr_ip_addr *addr)
167 {
168   struct hna_entry *new_entry;
169   olsr_u32_t hash;
170
171   new_entry = olsr_malloc(sizeof(struct hna_entry), "New HNA entry");
172
173   /* Fill struct */
174   COPY_IP(&new_entry->A_gateway_addr, addr);
175
176   /* Link nets */
177   new_entry->networks.next = &new_entry->networks;
178   new_entry->networks.prev = &new_entry->networks;
179
180   /* queue */
181   hash = olsr_hashing(addr);
182   
183   hna_set[hash].next->prev = new_entry;
184   new_entry->next = hna_set[hash].next;
185   hna_set[hash].next = new_entry;
186   new_entry->prev = &hna_set[hash];
187
188   return new_entry;
189
190 }
191
192
193
194 /**
195  *Adds a ntework entry to a HNA gateway
196  *
197  *@param hna_gw the gateway entry to add the
198  *network to
199  *@param net the networkaddress to add
200  *@param mask the netmask
201  *
202  *@return the newly created entry
203  */
204 struct hna_net *
205 olsr_add_hna_net(struct hna_entry *hna_gw, union olsr_ip_addr *net, union hna_netmask *mask)
206 {
207   struct hna_net *new_net;
208
209
210   /* Add the net */
211   new_net = olsr_malloc(sizeof(struct hna_net), "Add HNA net");
212   
213   /* Fill struct */
214   COPY_IP(&new_net->A_network_addr, net);
215   memcpy(&new_net->A_netmask, mask, netmask_size);
216
217   /* Queue */
218   hna_gw->networks.next->prev = new_net;
219   new_net->next = hna_gw->networks.next;
220   hna_gw->networks.next = new_net;
221   new_net->prev = &hna_gw->networks;
222
223   return new_net;
224 }
225
226
227
228
229 /**
230  * Update a HNA entry. If it does not exist it
231  * is created.
232  * This is the only function that should be called 
233  * from outside concerning creation of HNA entries.
234  *
235  *@param gw address of the gateway
236  *@param net address of the network
237  *@param mask the netmask
238  *@param vtime the validitytime of the entry
239  *
240  *@return nada
241  */
242 void
243 olsr_update_hna_entry(union olsr_ip_addr *gw, union olsr_ip_addr *net, union hna_netmask *mask, float vtime)
244 {
245   struct hna_entry *gw_entry;
246   struct hna_net *net_entry;
247
248   if((gw_entry = olsr_lookup_hna_gw(gw)) == NULL)
249     /* Need to add the entry */
250     gw_entry = olsr_add_hna_entry(gw);
251   
252   if((net_entry = olsr_lookup_hna_net(&gw_entry->networks, net, mask)) == NULL)
253     {
254       /* Need to add the net */
255       net_entry = olsr_add_hna_net(gw_entry, net, mask);
256       changes_hna = OLSR_TRUE;
257     }
258
259   /* Update holdingtime */
260   net_entry->A_time = GET_TIMESTAMP(vtime*1000);
261
262 }
263
264
265
266
267
268
269 /**
270  *Function that times out all entrys in the hna set and
271  *deletes the timed out ones.
272  *
273  *@return nada
274  */
275 void
276 olsr_time_out_hna_set(void *foo __attribute__((unused)))
277 {
278   int idx;
279
280   for(idx=0;idx<HASHSIZE;idx++)
281     {
282       struct hna_entry *tmp_hna = hna_set[idx].next;
283       /* Check all entrys */
284       while(tmp_hna != &hna_set[idx])
285         {
286           /* Check all networks */
287           struct hna_net *tmp_net = tmp_hna->networks.next;
288
289           while(tmp_net != &tmp_hna->networks)
290             {
291               if(TIMED_OUT(tmp_net->A_time))
292                 {
293                   struct hna_net *net_to_delete = tmp_net;
294                   tmp_net = tmp_net->next;
295                   DEQUEUE_ELEM(net_to_delete);
296                   free(net_to_delete);
297                   changes_hna = OLSR_TRUE;
298                 }
299               else
300                 tmp_net = tmp_net->next;
301             }
302
303           /* Delete gw entry if empty */
304           if(tmp_hna->networks.next == &tmp_hna->networks)
305             {
306               struct hna_entry *hna_to_delete = tmp_hna;
307               tmp_hna = tmp_hna->next;
308
309               /* Dequeue */
310               DEQUEUE_ELEM(hna_to_delete);
311               /* Delete */
312               free(hna_to_delete);
313             }
314           else
315             tmp_hna = tmp_hna->next;
316         }
317     }
318
319 }
320
321
322
323 /**
324  *Function that times out all entrys in the hna set and
325  *deletes the timed out ones.
326  *
327  *@return nada
328  */
329 void
330 olsr_print_hna_set(void)
331 {
332   int idx;
333
334   OLSR_PRINTF(1, "\n--- %02d:%02d:%02d.%02d ------------------------------------------------- HNA SET\n\n",
335               nowtm->tm_hour,
336               nowtm->tm_min,
337               nowtm->tm_sec,
338               (int)now.tv_usec/10000);
339   
340   if(olsr_cnf->ip_version == AF_INET)
341     OLSR_PRINTF(1, "IP net          netmask         GW IP\n");
342   else
343     OLSR_PRINTF(1, "IP net/prefixlen               GW IP\n");
344
345   for(idx=0;idx<HASHSIZE;idx++)
346     {
347       struct hna_entry *tmp_hna = hna_set[idx].next;
348       /* Check all entrys */
349       while(tmp_hna != &hna_set[idx])
350         {
351           /* Check all networks */
352           struct hna_net *tmp_net = tmp_hna->networks.next;
353
354           while(tmp_net != &tmp_hna->networks)
355             {
356               if(olsr_cnf->ip_version == AF_INET)
357                 {
358                   OLSR_PRINTF(1, "%-15s ", olsr_ip_to_string(&tmp_net->A_network_addr));
359                   OLSR_PRINTF(1, "%-15s ", olsr_ip_to_string((union olsr_ip_addr *)&tmp_net->A_netmask.v4));
360                   OLSR_PRINTF(1, "%-15s\n", olsr_ip_to_string(&tmp_hna->A_gateway_addr));
361                 }
362               else
363                 {
364                   OLSR_PRINTF(1, "%-27s/%d", olsr_ip_to_string(&tmp_net->A_network_addr), tmp_net->A_netmask.v6);
365                   OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&tmp_hna->A_gateway_addr));
366                 }
367
368               tmp_net = tmp_net->next;
369             }
370           tmp_hna = tmp_hna->next;
371         }
372     }
373
374 }
375
376 /*
377  * Local Variables:
378  * c-basic-offset: 2
379  * End:
380  */