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