87ab786bf03ef2e1fc313f14566fd55e54d54742
[olsrd.git] / src / hna_set.c
1
2 /*
3  * OLSR ad-hoc routing table management protocol
4  * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
5  *
6  * This file is part of the olsr.org OLSR daemon.
7  *
8  * olsr.org is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * olsr.org is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with olsr.org; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  * 
22  * 
23  * $ Id $
24  *
25  */
26
27 #include "defs.h"
28 #include "olsr.h"
29 #include "scheduler.h"
30
31
32 /**
33  *Initialize the HNA set
34  */
35 int
36 olsr_init_hna_set()
37 {
38
39   int index;
40
41   if(ipversion == AF_INET)
42     {
43       netmask_size = sizeof(olsr_u32_t);
44     }
45   else
46     {
47       netmask_size = sizeof(olsr_u16_t);
48     }
49
50   /* Since the holdingtime is assumed to be rather large for 
51    * HNA entries, the timeoutfunction is only ran once every second
52    */
53   olsr_register_scheduler_event(&olsr_time_out_hna_set, 1, 0, NULL);
54
55   for(index=0;index<HASHSIZE;index++)
56     {
57       hna_set[index].next = &hna_set[index];
58       hna_set[index].prev = &hna_set[index];
59     }
60
61   return 1;
62 }
63
64
65
66
67 /**
68  *Lookup a network entry in a networkentry list
69  *
70  *@param nets the network list to look in
71  *@param net the network to look for
72  *@param mask the netmask to look for
73  *
74  *@return the localted entry or NULL of not found
75  */
76 struct hna_net *
77 olsr_lookup_hna_net(struct hna_net *nets, union olsr_ip_addr *net, union hna_netmask *mask)
78 {
79   struct hna_net *tmp_net;
80
81
82   /* Loop trough entrys */
83   for(tmp_net = nets->next;
84       tmp_net != nets;
85       tmp_net = tmp_net->next)
86     { 
87       if(COMP_IP(&tmp_net->A_network_addr, net) &&
88          (memcmp(&tmp_net->A_netmask, mask, netmask_size) == 0))
89         return tmp_net;
90     }
91   
92   /* Not found */
93   return NULL;
94 }
95
96
97
98
99 /**
100  *Lookup a gateway entry
101  *
102  *@param gw the address of the gateway
103  *
104  *@return the located entry or NULL if not found
105  */
106 struct hna_entry *
107 olsr_lookup_hna_gw(union olsr_ip_addr *gw)
108 {
109   struct hna_entry *tmp_hna;
110   olsr_u32_t hash;
111
112   //olsr_printf(5, "TC: lookup entry\n");
113
114   hash = olsr_hashing(gw);
115   
116   /* Check for registered entry */
117   for(tmp_hna = hna_set[hash].next;
118       tmp_hna != &hna_set[hash];
119       tmp_hna = tmp_hna->next)
120     {
121       if(COMP_IP(&tmp_hna->A_gateway_addr, gw))
122         return tmp_hna;
123     }
124   
125   /* Not found */
126   return NULL;
127 }
128
129
130
131 /**
132  *Add a gatewayentry to the HNA set
133  *
134  *@param addr the address of the gateway
135  *
136  *@return the created entry
137  */
138 struct hna_entry *
139 olsr_add_hna_entry(union olsr_ip_addr *addr)
140 {
141   struct hna_entry *new_entry;
142   olsr_u32_t hash;
143
144   new_entry = olsr_malloc(sizeof(struct hna_entry), "New HNA entry");
145
146   /* Fill struct */
147   COPY_IP(&new_entry->A_gateway_addr, addr);
148
149   /* Link nets */
150   new_entry->networks.next = &new_entry->networks;
151   new_entry->networks.prev = &new_entry->networks;
152
153   /* queue */
154   hash = olsr_hashing(addr);
155   
156   hna_set[hash].next->prev = new_entry;
157   new_entry->next = hna_set[hash].next;
158   hna_set[hash].next = new_entry;
159   new_entry->prev = &hna_set[hash];
160
161   return new_entry;
162
163 }
164
165
166
167 /**
168  *Adds a ntework entry to a HNA gateway
169  *
170  *@param hna_gw the gateway entry to add the
171  *network to
172  *@param net the networkaddress to add
173  *@param mask the netmask
174  *
175  *@return the newly created entry
176  */
177 struct hna_net *
178 olsr_add_hna_net(struct hna_entry *hna_gw, union olsr_ip_addr *net, union hna_netmask *mask)
179 {
180   struct hna_net *new_net;
181
182
183   /* Add the net */
184   new_net = olsr_malloc(sizeof(struct hna_net), "Add HNA net");
185   
186   /* Fill struct */
187   COPY_IP(&new_net->A_network_addr, net);
188   memcpy(&new_net->A_netmask, mask, netmask_size);
189
190   /* Queue */
191   hna_gw->networks.next->prev = new_net;
192   new_net->next = hna_gw->networks.next;
193   hna_gw->networks.next = new_net;
194   new_net->prev = &hna_gw->networks;
195
196   return new_net;
197 }
198
199
200
201
202 /**
203  * Update a HNA entry. If it does not exist it
204  * is created.
205  * This is the only function that should be called 
206  * from outside concerning creation of HNA entries.
207  *
208  *@param gw address of the gateway
209  *@param net address of the network
210  *@param mask the netmask
211  *@param vtime the validitytime of the entry
212  *
213  *@return nada
214  */
215 void
216 olsr_update_hna_entry(union olsr_ip_addr *gw, union olsr_ip_addr *net, union hna_netmask *mask, float vtime)
217 {
218   struct hna_entry *gw_entry;
219   struct hna_net *net_entry;
220
221   if((gw_entry = olsr_lookup_hna_gw(gw)) == NULL)
222     /* Need to add the entry */
223     gw_entry = olsr_add_hna_entry(gw);
224   
225   if((net_entry = olsr_lookup_hna_net(&gw_entry->networks, net, mask)) == NULL)
226     {
227       /* Need to add the net */
228       net_entry = olsr_add_hna_net(gw_entry, net, mask);
229       changes_hna = UP;
230     }
231
232   /* Update holdingtime */
233   olsr_get_timestamp((olsr_u32_t) vtime*1000, &net_entry->A_time);
234
235 }
236
237
238
239
240
241
242 /**
243  *Function that times out all entrys in the hna set and
244  *deletes the timed out ones.
245  *
246  *@return nada
247  */
248 void
249 olsr_time_out_hna_set()
250 {
251   int index;
252   struct hna_entry *tmp_hna, *hna_to_delete;
253   struct hna_net *tmp_net, *net_to_delete;
254
255   for(index=0;index<HASHSIZE;index++)
256     {
257       tmp_hna = hna_set[index].next;
258       /* Check all entrys */
259       while(tmp_hna != &hna_set[index])
260         {
261           /* Check all networks */
262           tmp_net = tmp_hna->networks.next;
263
264           while(tmp_net != &tmp_hna->networks)
265             {
266               if(TIMED_OUT(&tmp_net->A_time))
267                 {
268                   net_to_delete = tmp_net;
269                   tmp_net = tmp_net->next;
270                   delete_hna_net(net_to_delete);
271                   changes_hna = UP;
272                 }
273               else
274                 tmp_net = tmp_net->next;
275             }
276
277           /* Delete gw entry if empty */
278           if(tmp_hna->networks.next == &tmp_hna->networks)
279             {
280               hna_to_delete = tmp_hna;
281               tmp_hna = tmp_hna->next;
282               delete_hna_entry(hna_to_delete);
283             }
284           else
285             tmp_hna = tmp_hna->next;
286         }
287     }
288
289 }
290
291
292
293
294
295
296 /**
297  *Deletes and dequeues a HNA network entry
298  *
299  *@param net the entry to delete
300  */
301 void
302 delete_hna_net(struct hna_net *net)
303 {
304
305   /* Dequeue */
306   net->prev->next = net->next;
307   net->next->prev = net->prev;
308
309   /* Delete */
310   free(net);
311
312 }
313
314
315
316
317 /**
318  *Deletes and dequeues a hna gw entry
319  *NETWORKS MUST BE DELETED FIRST!
320  *
321  *@param entry the entry to delete
322  */
323 void
324 delete_hna_entry(struct hna_entry *entry)
325 {
326   /* Dequeue */
327   entry->prev->next = entry->next;
328   entry->next->prev = entry->prev;
329
330   /* Delete */
331   free(entry);
332 }
333
334
335
336
337