2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
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.
33 * Visit http://www.olsr.org for more information.
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.
44 #include "scheduler.h"
49 struct hna_entry hna_set[HASHSIZE];
50 struct olsr_cookie_info *hna_net_timer_cookie = NULL;
53 * Initialize the HNA set
56 olsr_init_hna_set(void)
60 for(idx=0;idx<HASHSIZE;idx++) {
61 hna_set[idx].next = &hna_set[idx];
62 hna_set[idx].prev = &hna_set[idx];
65 hna_net_timer_cookie =
66 olsr_alloc_cookie("HNA Network", OLSR_COOKIE_TYPE_TIMER);
72 *Lookup a network entry in a networkentry list
74 *@param nets the network list to look in
75 *@param net the network to look for
76 *@param mask the netmask to look for
78 *@return the localted entry or NULL of not found
81 olsr_lookup_hna_net(const struct hna_net *nets, const union olsr_ip_addr *net,
85 /* Loop trough entrys */
86 for (tmp = nets->next; tmp != nets; tmp = tmp->next) {
87 if (tmp->prefixlen == prefixlen && ipequal(&tmp->A_network_addr, net)) {
97 * Lookup a gateway entry
99 * @param gw the address of the gateway
100 * @return the located entry or NULL if not found
103 olsr_lookup_hna_gw(const union olsr_ip_addr *gw)
105 struct hna_entry *tmp_hna;
106 olsr_u32_t hash = olsr_ip_hashing(gw);
109 OLSR_PRINTF(5, "HNA: lookup entry\n");
111 /* Check for registered entry */
113 for(tmp_hna = hna_set[hash].next;
114 tmp_hna != &hna_set[hash];
115 tmp_hna = tmp_hna->next) {
116 if(ipequal(&tmp_hna->A_gateway_addr, gw)) {
128 *Add a gatewayentry to the HNA set
130 *@param addr the address of the gateway
132 *@return the created entry
135 olsr_add_hna_entry(const union olsr_ip_addr *addr)
137 struct hna_entry *new_entry;
140 new_entry = olsr_malloc(sizeof(struct hna_entry), "New HNA entry");
143 new_entry->A_gateway_addr = *addr;
146 new_entry->networks.next = &new_entry->networks;
147 new_entry->networks.prev = &new_entry->networks;
150 hash = olsr_ip_hashing(addr);
152 hna_set[hash].next->prev = new_entry;
153 new_entry->next = hna_set[hash].next;
154 hna_set[hash].next = new_entry;
155 new_entry->prev = &hna_set[hash];
164 *Adds a ntework entry to a HNA gateway
166 *@param hna_gw the gateway entry to add the
168 *@param net the networkaddress to add
169 *@param mask the netmask
171 *@return the newly created entry
174 olsr_add_hna_net(struct hna_entry *hna_gw, const union olsr_ip_addr *net, olsr_u8_t prefixlen)
177 struct hna_net *new_net = olsr_malloc(sizeof(struct hna_net), "Add HNA net");
180 memset(new_net, 0, sizeof(struct hna_net));
181 new_net->A_network_addr = *net;
182 new_net->prefixlen = prefixlen;
184 /* Set backpointer */
185 new_net->hna_gw = hna_gw;
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;
194 * Add the rt_path for the entry.
196 olsr_insert_routing_table(&new_net->A_network_addr,
198 &hna_gw->A_gateway_addr,
205 * Callback for the hna_net timer.
208 olsr_expire_hna_net_entry(void *context)
210 #if !defined(NODEBUG) && defined(DEBUG)
211 struct ipaddr_str buf1, buf2;
213 struct hna_net *net_to_delete;
214 struct hna_entry *hna_gw;
216 net_to_delete = (struct hna_net *)context;
217 net_to_delete->hna_net_timer = NULL; /* be pedandic */
218 hna_gw = net_to_delete->hna_gw;
221 OLSR_PRINTF(5, "HNA: timeout %s/%u via hna-gw %s\n",
222 olsr_ip_to_string(&buf1, &net_to_delete->A_network_addr),
223 net_to_delete->prefixlen,
224 olsr_ip_to_string(&buf2, &hna_gw->A_gateway_addr));
228 * Delete the rt_path for the entry.
230 olsr_delete_routing_table(&net_to_delete->A_network_addr,
231 net_to_delete->prefixlen,
232 &hna_gw->A_gateway_addr);
235 /* Delete hna_gw if empty */
236 if (hna_gw->networks.next == &hna_gw->networks) {
237 DEQUEUE_ELEM(hna_gw);
243 * Update a HNA entry. If it does not exist it
245 * This is the only function that should be called
246 * from outside concerning creation of HNA entries.
248 *@param gw address of the gateway
249 *@param net address of the network
250 *@param mask the netmask
251 *@param vtime the validitytime of the entry
256 olsr_update_hna_entry(const union olsr_ip_addr *gw, const union olsr_ip_addr *net,
257 olsr_u8_t prefixlen, olsr_reltime vtime)
259 struct hna_entry *gw_entry;
260 struct hna_net *net_entry;
262 gw_entry = olsr_lookup_hna_gw(gw);
265 /* Need to add the entry */
266 gw_entry = olsr_add_hna_entry(gw);
269 net_entry = olsr_lookup_hna_net(&gw_entry->networks, net, prefixlen);
270 if (net_entry == NULL) {
272 /* Need to add the net */
273 net_entry = olsr_add_hna_net(gw_entry, net, prefixlen);
274 changes_hna = OLSR_TRUE;
277 olsr_set_timer(&net_entry->hna_net_timer, vtime,
278 OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT,
279 &olsr_expire_hna_net_entry, net_entry,
280 hna_net_timer_cookie);
285 * Print all HNA entries.
290 olsr_print_hna_set(void)
293 /* The whole function doesn't do anything else. */
296 OLSR_PRINTF(1, "\n--- %02d:%02d:%02d.%02d ------------------------------------------------- HNA SET\n\n",
300 (int)now.tv_usec/10000);
302 if(olsr_cnf->ip_version == AF_INET)
303 OLSR_PRINTF(1, "IP net netmask GW IP\n");
305 OLSR_PRINTF(1, "IP net/prefixlen GW IP\n");
307 for(idx=0;idx<HASHSIZE;idx++)
309 struct hna_entry *tmp_hna = hna_set[idx].next;
310 /* Check all entrys */
311 while(tmp_hna != &hna_set[idx])
313 /* Check all networks */
314 struct hna_net *tmp_net = tmp_hna->networks.next;
316 while(tmp_net != &tmp_hna->networks)
318 if(olsr_cnf->ip_version == AF_INET)
321 struct ipaddr_str buf;
323 OLSR_PRINTF(1, "%-15s ", olsr_ip_to_string(&buf, &tmp_net->A_network_addr));
324 OLSR_PRINTF(1, "%-15d ", tmp_net->prefix_len);
325 OLSR_PRINTF(1, "%-15s\n", olsr_ip_to_string(&buf, &tmp_hna->A_gateway_addr));
330 struct ipaddr_str buf;
332 OLSR_PRINTF(1, "%-27s/%d", olsr_ip_to_string(&buf, &tmp_net->A_network_addr), tmp_net->A_netmask.v6);
333 OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&buf, &tmp_hna->A_gateway_addr));
336 tmp_net = tmp_net->next;
338 tmp_hna = tmp_hna->next;