b3c2950026276f2f5f33fadfe2025cbcfb6e5dde
[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  */
40
41 #include "ipcalc.h"
42 #include "defs.h"
43 #include "olsr.h"
44 #include "scheduler.h"
45 #include "net_olsr.h"
46 #include "tc_set.h"
47
48
49 struct hna_entry hna_set[HASHSIZE];
50 struct olsr_cookie_info *hna_net_timer_cookie = NULL;
51 struct olsr_cookie_info *hna_entry_mem_cookie = NULL;
52 struct olsr_cookie_info *hna_net_mem_cookie = NULL;
53
54 /**
55  * Initialize the HNA set
56  */
57 int
58 olsr_init_hna_set(void)
59 {
60   int idx;
61
62   for(idx=0;idx<HASHSIZE;idx++) {
63     hna_set[idx].next = &hna_set[idx];
64     hna_set[idx].prev = &hna_set[idx];
65   }
66
67   hna_net_timer_cookie =
68     olsr_alloc_cookie("HNA Network", OLSR_COOKIE_TYPE_TIMER);
69
70   hna_net_mem_cookie =
71     olsr_alloc_cookie("hna_net", OLSR_COOKIE_TYPE_MEMORY);
72   olsr_cookie_set_memory_size(hna_net_mem_cookie, sizeof(struct hna_net));
73
74   hna_entry_mem_cookie =
75     olsr_alloc_cookie("hna_entry", OLSR_COOKIE_TYPE_MEMORY);
76   olsr_cookie_set_memory_size(hna_entry_mem_cookie, sizeof(struct hna_entry));
77
78   return 1;
79 }
80
81 /**
82  *Lookup a network entry in a networkentry list
83  *
84  *@param nets the network list to look in
85  *@param net the network to look for
86  *@param mask the netmask to look for
87  *
88  *@return the localted entry or NULL of not found
89  */
90 struct hna_net *
91 olsr_lookup_hna_net(const struct hna_net *nets, const union olsr_ip_addr *net,
92                     olsr_u8_t prefixlen)
93 {
94   struct hna_net *tmp;
95   /* Loop trough entrys */
96   for (tmp = nets->next; tmp != nets; tmp = tmp->next) { 
97     if (tmp->prefixlen == prefixlen && ipequal(&tmp->A_network_addr, net)) {
98       return tmp;
99     }
100   }
101   /* Not found */
102   return NULL;
103 }
104
105
106 /**
107  * Lookup a gateway entry
108  *
109  * @param gw the address of the gateway
110  * @return the located entry or NULL if not found
111  */
112 struct hna_entry *
113 olsr_lookup_hna_gw(const union olsr_ip_addr *gw)
114 {
115   struct hna_entry *tmp_hna;
116   olsr_u32_t hash = olsr_ip_hashing(gw);
117
118 #if 0
119   OLSR_PRINTF(5, "HNA: lookup entry\n");
120 #endif
121     /* Check for registered entry */
122
123   for(tmp_hna = hna_set[hash].next;
124       tmp_hna != &hna_set[hash];
125       tmp_hna = tmp_hna->next) {
126     if(ipequal(&tmp_hna->A_gateway_addr, gw)) {
127       return tmp_hna;
128     }
129   }
130   
131   /* Not found */
132   return NULL;
133 }
134
135
136
137 /**
138  *Add a gatewayentry to the HNA set
139  *
140  *@param addr the address of the gateway
141  *
142  *@return the created entry
143  */
144 struct hna_entry *
145 olsr_add_hna_entry(const union olsr_ip_addr *addr)
146 {
147   struct hna_entry *new_entry;
148   olsr_u32_t hash;
149
150   new_entry = olsr_cookie_malloc(hna_entry_mem_cookie);
151
152   /* Fill struct */
153   new_entry->A_gateway_addr = *addr;
154
155   /* Link nets */
156   new_entry->networks.next = &new_entry->networks;
157   new_entry->networks.prev = &new_entry->networks;
158
159   /* queue */
160   hash = olsr_ip_hashing(addr);
161   
162   hna_set[hash].next->prev = new_entry;
163   new_entry->next = hna_set[hash].next;
164   hna_set[hash].next = new_entry;
165   new_entry->prev = &hna_set[hash];
166
167   return new_entry;
168
169 }
170
171
172
173 /**
174  *Adds a ntework entry to a HNA gateway
175  *
176  *@param hna_gw the gateway entry to add the
177  *network to
178  *@param net the networkaddress to add
179  *@param mask the netmask
180  *
181  *@return the newly created entry
182  */
183 struct hna_net *
184 olsr_add_hna_net(struct hna_entry *hna_gw, const union olsr_ip_addr *net, olsr_u8_t prefixlen)
185 {
186   /* Add the net */
187   struct hna_net *new_net = olsr_cookie_malloc(hna_net_mem_cookie);
188   
189   /* Fill struct */
190   memset(new_net, 0, sizeof(struct hna_net));
191   new_net->A_network_addr = *net;
192   new_net->prefixlen = prefixlen;
193
194   /* Set backpointer */
195   new_net->hna_gw = hna_gw;
196
197   /* Queue */
198   hna_gw->networks.next->prev = new_net;
199   new_net->next = hna_gw->networks.next;
200   hna_gw->networks.next = new_net;
201   new_net->prev = &hna_gw->networks;
202
203   /*
204    * Add the rt_path for the entry.
205    */
206   olsr_insert_routing_table(&new_net->A_network_addr,
207                             new_net->prefixlen,
208                             &hna_gw->A_gateway_addr,
209                             OLSR_RT_ORIGIN_HNA);
210
211   return new_net;
212 }
213
214 /**
215  * Callback for the hna_net timer.
216  */
217 static void
218 olsr_expire_hna_net_entry(void *context)
219 {
220 #if !defined(NODEBUG) && defined(DEBUG)
221   struct ipaddr_str buf1, buf2;
222 #endif
223   struct hna_net *net_to_delete;
224   struct hna_entry *hna_gw;
225
226   net_to_delete = (struct hna_net *)context;
227   net_to_delete->hna_net_timer = NULL; /* be pedandic */
228   hna_gw = net_to_delete->hna_gw;
229
230 #ifdef DEBUG
231   OLSR_PRINTF(5, "HNA: timeout %s/%u via hna-gw %s\n", 
232               olsr_ip_to_string(&buf1, &net_to_delete->A_network_addr),
233               net_to_delete->prefixlen,
234               olsr_ip_to_string(&buf2, &hna_gw->A_gateway_addr));
235 #endif
236
237   /*
238    * Delete the rt_path for the entry.
239    */
240   olsr_delete_routing_table(&net_to_delete->A_network_addr,
241                             net_to_delete->prefixlen,
242                             &hna_gw->A_gateway_addr);
243
244
245   /* Delete hna_gw if empty */
246   if (hna_gw->networks.next == &hna_gw->networks) {
247     DEQUEUE_ELEM(hna_gw);
248     olsr_cookie_free(hna_entry_mem_cookie, hna_gw);
249   }
250
251   olsr_cookie_free(hna_net_mem_cookie, net_to_delete);
252 }
253
254 /**
255  * Update a HNA entry. If it does not exist it
256  * is created.
257  * This is the only function that should be called 
258  * from outside concerning creation of HNA entries.
259  *
260  *@param gw address of the gateway
261  *@param net address of the network
262  *@param mask the netmask
263  *@param vtime the validitytime of the entry
264  *
265  *@return nada
266  */
267 void
268 olsr_update_hna_entry(const union olsr_ip_addr *gw, const union olsr_ip_addr *net,
269                       olsr_u8_t prefixlen, olsr_reltime vtime)
270 {
271   struct hna_entry *gw_entry;
272   struct hna_net *net_entry;
273
274   gw_entry = olsr_lookup_hna_gw(gw);
275   if (!gw_entry) {
276
277     /* Need to add the entry */
278     gw_entry = olsr_add_hna_entry(gw);
279   }
280
281   net_entry = olsr_lookup_hna_net(&gw_entry->networks, net, prefixlen);
282   if (net_entry == NULL)  {
283
284     /* Need to add the net */
285     net_entry = olsr_add_hna_net(gw_entry, net, prefixlen);
286     changes_hna = OLSR_TRUE;
287   }
288
289   olsr_set_timer(&net_entry->hna_net_timer, vtime,
290                  OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT,
291                  &olsr_expire_hna_net_entry, net_entry,
292                  hna_net_timer_cookie->ci_id);
293 }
294
295
296 /**
297  * Print all HNA entries.
298  *
299  *@return nada
300  */
301 void
302 olsr_print_hna_set(void)
303 {
304 #ifdef NODEBUG
305   /* The whole function doesn't do anything else. */
306   int idx;
307
308   OLSR_PRINTF(1, "\n--- %02d:%02d:%02d.%02d ------------------------------------------------- HNA SET\n\n",
309               nowtm->tm_hour,
310               nowtm->tm_min,
311               nowtm->tm_sec,
312               (int)now.tv_usec/10000);
313   
314   if(olsr_cnf->ip_version == AF_INET)
315     OLSR_PRINTF(1, "IP net          netmask         GW IP\n");
316   else
317     OLSR_PRINTF(1, "IP net/prefixlen               GW IP\n");
318
319   for(idx=0;idx<HASHSIZE;idx++)
320     {
321       struct hna_entry *tmp_hna = hna_set[idx].next;
322       /* Check all entrys */
323       while(tmp_hna != &hna_set[idx])
324         {
325           /* Check all networks */
326           struct hna_net *tmp_net = tmp_hna->networks.next;
327
328           while(tmp_net != &tmp_hna->networks)
329             {
330               if(olsr_cnf->ip_version == AF_INET)
331                 {
332 #ifndef NODEBUG
333                   struct ipaddr_str buf;
334 #endif
335                   OLSR_PRINTF(1, "%-15s ", olsr_ip_to_string(&buf, &tmp_net->A_network_addr));
336                   OLSR_PRINTF(1, "%-15d ", tmp_net->prefix_len);
337                   OLSR_PRINTF(1, "%-15s\n", olsr_ip_to_string(&buf, &tmp_hna->A_gateway_addr));
338                 }
339               else
340                 {
341 #ifndef NODEBUG
342                   struct ipaddr_str buf;
343 #endif
344                   OLSR_PRINTF(1, "%-27s/%d", olsr_ip_to_string(&buf, &tmp_net->A_network_addr), tmp_net->A_netmask.v6);
345                   OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&buf, &tmp_hna->A_gateway_addr));
346                 }
347
348               tmp_net = tmp_net->next;
349             }
350           tmp_hna = tmp_hna->next;
351         }
352     }
353 #endif
354 }
355
356 /*
357  * Local Variables:
358  * c-basic-offset: 2
359  * End:
360  */