HNA refactoring phase #1
[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 /* Some cookies for stats keeping */
49 struct olsr_cookie_info *hna_net_timer_cookie = NULL;
50 struct olsr_cookie_info *hna_net_mem_cookie = NULL;
51
52 /**
53  * Initialize the HNA set
54  */
55 void
56 olsr_init_hna_set(void)
57 {
58   OLSR_PRINTF(5, "HNA: init\n");
59
60   hna_net_timer_cookie =
61     olsr_alloc_cookie("HNA Network", OLSR_COOKIE_TYPE_TIMER);
62
63   hna_net_mem_cookie =
64     olsr_alloc_cookie("hna_net", OLSR_COOKIE_TYPE_MEMORY);
65   olsr_cookie_set_memory_size(hna_net_mem_cookie, sizeof(struct hna_net));
66 }
67
68 /**
69  * Lookup a network entry in the HNA subtree.
70  *
71  * @param tc the HNA hookup point
72  * @param prefic the prefix to look for
73  *
74  * @return the localized entry or NULL of not found
75  */
76 static struct hna_net *
77 olsr_lookup_hna_net(struct tc_entry *tc, struct olsr_ip_prefix *prefix)
78 {
79   return (hna_tc_tree2hna(avl_find(&tc->hna_tree, prefix)));
80 }
81
82 /**
83  * Adds a network entry to a HNA gateway.
84  *
85  * @param tc the gateway entry to add the network to
86  * @param net the nework prefix to add
87  * @param prefixlen the prefix length
88  *
89  * @return the newly created entry
90  */
91 static struct hna_net *
92 olsr_add_hna_net(struct tc_entry *tc, struct olsr_ip_prefix *prefix)
93 {
94   /* Add the net */
95   struct hna_net *new_net = olsr_cookie_malloc(hna_net_mem_cookie);
96   
97   /* Fill struct */
98   new_net->hna_prefix = *prefix;
99
100   /* Set backpointer */
101   new_net->hna_tc = tc;
102   olsr_lock_tc_entry(tc);
103
104   /*
105    * Insert into the per-tc hna subtree.
106    */
107   new_net->hna_tc_node.key = &new_net->hna_prefix;
108   avl_insert(&tc->hna_tree, &new_net->hna_tc_node, AVL_DUP_NO);
109
110   return new_net;
111 }
112
113 /**
114  * Delete a single HNA network.
115  * 
116  * @param hna_net the hna_net to delete.
117  */
118 static void
119 olsr_delete_hna_net(struct hna_net *hna_net)
120 {
121   struct tc_entry *tc;
122
123   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 #ifdef DEBUG
151   struct ipaddr_str buf1, buf2;
152 #endif
153   struct hna_net *hna_net;
154
155   hna_net = (struct hna_net *)context;
156   hna_net->hna_net_timer = NULL; /* be pedandic */
157
158 #ifdef DEBUG
159   OLSR_PRINTF(5, "HNA: timeout %s/%u via hna-gw %s\n", 
160               olsr_ip_to_string(&buf1, &hna_net->A_network_addr),
161               hna_net->prefixlen,
162               olsr_ip_to_string(&buf2, &hna_net->hna_tc->addr));
163 #endif
164
165   olsr_delete_hna_net(hna_net);
166 }
167
168 /**
169  * Update a HNA entry. If it does not exist it
170  * is created.
171  * This is the only function that should be called 
172  * from outside concerning creation of HNA entries.
173  *
174  *@param gw address of the gateway
175  *@param net address of the network
176  *@param mask the netmask
177  *@param vtime the validitytime of the entry
178  *
179  *@return nada
180  */
181 void
182 olsr_update_hna_entry(const union olsr_ip_addr *gw, const union olsr_ip_addr *net,
183                       olsr_u8_t prefixlen, olsr_reltime vtime)
184 {
185   struct tc_entry *tc;
186   struct hna_net *net_entry;
187   struct olsr_ip_prefix prefix;
188
189   tc = olsr_locate_tc_entry(gw);
190
191   prefix.prefix = *net;
192   prefix.prefix_len = prefixlen;
193   net_entry = olsr_lookup_hna_net(tc, &prefix);
194   if (net_entry == NULL) {
195
196     /* Need to add the net */
197     net_entry = olsr_add_hna_net(tc, &prefix);
198     changes_hna = OLSR_TRUE;
199   }
200
201   /*
202    * Add the rt_path for the entry.
203    */
204   olsr_insert_routing_table(&net_entry->hna_prefix.prefix,
205                             net_entry->hna_prefix.prefix_len,
206                             &tc->addr,
207                             OLSR_RT_ORIGIN_HNA);
208
209   /*
210    * Start, or refresh the timer, whatever is appropriate.
211    */
212   olsr_set_timer(&net_entry->hna_net_timer, vtime,
213                  OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT,
214                  &olsr_expire_hna_net_entry, net_entry,
215                  hna_net_timer_cookie->ci_id);
216 }
217
218 /**
219  * Print all HNA entries.
220  *
221  *@return nada
222  */
223 void
224 olsr_print_hna_set(void)
225 {
226 #ifdef NODEBUG
227   struct tc_entry *tc;
228   struct hna_net *hna_net;
229
230   /* The whole function doesn't do anything else. */
231
232   OLSR_PRINTF(1,
233               "\n--- %s ------------------------------------------------- HNA\n\n",
234               olsr_wallclock_string());
235
236   OLSR_FOR_ALL_TC_ENTRIES(tc) {
237     OLSR_PRINTF(1, "HNA-gw %s: ", olsr_ip_to_string(&buf, &tc->addr));
238     OLSR_FOR_ALL_TC_HNA_ENTRIES(tc, hna_net) {
239       OLSR_PRINTF(1, "%-27s", olsr_ip_prefix_to_string(hna_net->hna_prefix);
240                   } OLSR_FOR_ALL_TC_HNA_ENTRIES_END(tc, hna_net);
241       OLSR_PRINTF(1, "\n");
242     } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
243 #endif
244   }
245
246 /*
247  * Local Variables:
248  * c-basic-offset: 2
249  * End:
250  */