3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
47 #include "scheduler.h"
50 #include "olsr_ip_prefix_list.h"
51 #include "olsr_logging.h"
53 /* Some cookies for stats keeping */
54 static struct olsr_cookie_info *hna_net_timer_cookie = NULL;
55 static struct olsr_cookie_info *hna_net_mem_cookie = NULL;
58 * Initialize the HNA set
61 olsr_init_hna_set(void)
63 OLSR_INFO(LOG_HNA, "Initialize HNA set...\n");
65 hna_net_timer_cookie = olsr_alloc_cookie("HNA Network", OLSR_COOKIE_TYPE_TIMER);
67 hna_net_mem_cookie = olsr_alloc_cookie("hna_net", OLSR_COOKIE_TYPE_MEMORY);
68 olsr_cookie_set_memory_size(hna_net_mem_cookie, sizeof(struct hna_net));
72 * Lookup a network entry in the HNA subtree.
74 * @param tc the HNA hookup point
75 * @param prefic the prefix to look for
77 * @return the localized entry or NULL of not found
79 static struct hna_net *
80 olsr_lookup_hna_net(struct tc_entry *tc, const struct olsr_ip_prefix *prefix)
82 return (hna_tc_tree2hna(avl_find(&tc->hna_tree, prefix)));
86 * Adds a network entry to a HNA gateway.
88 * @param tc the gateway entry to add the network to
89 * @param net the nework prefix to add
90 * @param prefixlen the prefix length
92 * @return the newly created entry
94 static struct hna_net *
95 olsr_add_hna_net(struct tc_entry *tc, const struct olsr_ip_prefix *prefix)
98 struct hna_net *new_net = olsr_cookie_malloc(hna_net_mem_cookie);
101 new_net->hna_prefix = *prefix;
103 /* Set backpointer */
104 new_net->hna_tc = tc;
105 olsr_lock_tc_entry(tc);
108 * Insert into the per-tc hna subtree.
110 new_net->hna_tc_node.key = &new_net->hna_prefix;
111 avl_insert(&tc->hna_tree, &new_net->hna_tc_node, AVL_DUP_NO);
117 * Delete a single HNA network.
119 * @param hna_net the hna_net to delete.
122 olsr_delete_hna_net(struct hna_net *hna_net)
124 struct tc_entry *tc = hna_net->hna_tc;
127 * Delete the rt_path for the hna_net.
129 olsr_delete_routing_table(&hna_net->hna_prefix.prefix, hna_net->hna_prefix.prefix_len, &tc->addr, OLSR_RT_ORIGIN_HNA);
132 * Remove from the per-tc tree.
134 avl_delete(&tc->hna_tree, &hna_net->hna_tc_node);
139 olsr_unlock_tc_entry(tc);
140 olsr_cookie_free(hna_net_mem_cookie, hna_net);
144 * Delete all the HNA nets hanging off a tc entry.
146 * @param entry the tc entry holding the HNA networks.
149 olsr_flush_hna_nets(struct tc_entry *tc)
151 struct hna_net *hna_net;
153 OLSR_FOR_ALL_TC_HNA_ENTRIES(tc, hna_net) {
154 olsr_delete_hna_net(hna_net);
155 } OLSR_FOR_ALL_TC_HNA_ENTRIES_END(tc, hna_net);
159 * Callback for the hna_net timer.
162 olsr_expire_hna_net_entry(void *context)
164 struct hna_net *hna_net = context;
165 #if !defined REMOVE_LOG_DEBUG
166 struct ipaddr_str buf;
167 struct ipprefix_str prefixstr;
170 OLSR_DEBUG(5, "HNA: timeout %s via hna-gw %s\n",
171 olsr_ip_prefix_to_string(&prefixstr, &hna_net->hna_prefix), olsr_ip_to_string(&buf, &hna_net->hna_tc->addr));
173 hna_net->hna_net_timer = NULL; /* be pedandic */
175 olsr_delete_hna_net(hna_net);
179 * Update a HNA entry. If it does not exist it
181 * This is the only function that should be called
182 * from outside concerning creation of HNA entries.
184 *@param gw address of the gateway
185 *@param net address of the network
186 *@param mask the netmask
187 *@param vtime the validitytime of the entry
192 olsr_update_hna_entry(const union olsr_ip_addr *gw, const struct olsr_ip_prefix *prefix, olsr_reltime vtime)
194 struct tc_entry *tc = olsr_locate_tc_entry(gw);
195 struct hna_net *net_entry = olsr_lookup_hna_net(tc, prefix);
197 if (net_entry == NULL) {
198 /* Need to add the net */
199 net_entry = olsr_add_hna_net(tc, prefix);
204 * Add the rt_path for the entry.
206 olsr_insert_routing_table(&net_entry->hna_prefix.prefix, net_entry->hna_prefix.prefix_len, &tc->addr, OLSR_RT_ORIGIN_HNA);
209 * Start, or refresh the timer, whatever is appropriate.
211 olsr_set_timer(&net_entry->hna_net_timer, vtime,
212 OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT, &olsr_expire_hna_net_entry, net_entry, hna_net_timer_cookie->ci_id);
216 * Print all HNA entries.
221 olsr_print_hna_set(void)
223 /* The whole function doesn't do anything else. */
224 #if !defined REMOVE_LOG_INFO
226 struct ipaddr_str buf;
227 struct ipprefix_str prefixstr;
228 struct hna_net *hna_net;
230 OLSR_INFO(LOG_HNA, "\n--- %s ------------------------------------------------- HNA\n\n", olsr_wallclock_string());
232 OLSR_FOR_ALL_TC_ENTRIES(tc) {
233 OLSR_INFO_NH(LOG_HNA, "HNA-gw %s:\n", olsr_ip_to_string(&buf, &tc->addr));
235 OLSR_FOR_ALL_TC_HNA_ENTRIES(tc, hna_net) {
236 OLSR_INFO_NH(LOG_HNA, "\t%-27s\n", olsr_ip_prefix_to_string(&prefixstr, &hna_net->hna_prefix));
237 } OLSR_FOR_ALL_TC_HNA_ENTRIES_END(tc, hna_net);
238 } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
243 * Process incoming HNA message.
244 * Forwards the message if that is to be done.
247 olsr_input_hna(union olsr_message *msg, struct interface *in_if __attribute__ ((unused)), union olsr_ip_addr *from_addr)
249 struct olsrmsg_hdr msg_hdr;
250 struct olsr_ip_prefix prefix;
251 const uint8_t *curr, *curr_end;
252 #if !defined REMOVE_LOG_DEBUG
253 struct ipaddr_str buf;
256 if (!(curr = olsr_parse_msg_hdr(msg, &msg_hdr))) {
260 /* We are only interested in HNA message types. */
261 if (msg_hdr.type != HNA_MESSAGE) {
266 * If the sender interface (NB: not originator) of this message
267 * is not in the symmetric 1-hop neighborhood of this node, the
268 * message MUST be discarded.
270 if (check_neighbor_link(from_addr) != SYM_LINK) {
271 OLSR_DEBUG(LOG_HNA, "Received HNA from NON SYM neighbor %s\n", olsr_ip_to_string(&buf, from_addr));
275 OLSR_DEBUG(LOG_HNA, "Processing HNA from %s, seq 0x%04x\n", olsr_ip_to_string(&buf, &msg_hdr.originator), msg_hdr.seqno);
278 * Now walk the list of HNA advertisements.
280 curr_end = (const uint8_t *)msg + msg_hdr.size;
281 while (curr < curr_end) {
283 pkt_get_ipaddress(&curr, &prefix.prefix);
284 pkt_get_prefixlen(&curr, &prefix.prefix_len);
286 if (!ip_prefix_list_find(&olsr_cnf->hna_entries, &prefix.prefix, prefix.prefix_len, olsr_cnf->ip_version)) {
288 * Only update if it's not from us.
290 olsr_update_hna_entry(&msg_hdr.originator, &prefix, msg_hdr.vtime);
293 /* Forward the message */
300 * indent-tabs-mode: nil