More Logger stuff
[olsrd.git] / src / hna_set.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
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 "hna_set.h"
42 #include "ipcalc.h"
43 #include "defs.h"
44 #include "parser.h"
45 #include "olsr.h"
46 #include "scheduler.h"
47 #include "net_olsr.h"
48 #include "tc_set.h"
49 #include "olsr_ip_prefix_list.h"
50 #include "olsr_logging.h"
51
52 /* Some cookies for stats keeping */
53 static struct olsr_cookie_info *hna_net_timer_cookie = NULL;
54 static struct olsr_cookie_info *hna_net_mem_cookie = NULL;
55
56 /**
57  * Initialize the HNA set
58  */
59 void
60 olsr_init_hna_set(void)
61 {
62   OLSR_DEBUG(LOG_HNA, "HNA: init\n");
63
64   hna_net_timer_cookie =
65     olsr_alloc_cookie("HNA Network", OLSR_COOKIE_TYPE_TIMER);
66
67   hna_net_mem_cookie =
68     olsr_alloc_cookie("hna_net", OLSR_COOKIE_TYPE_MEMORY);
69   olsr_cookie_set_memory_size(hna_net_mem_cookie, sizeof(struct hna_net));
70 }
71
72 /**
73  * Lookup a network entry in the HNA subtree.
74  *
75  * @param tc the HNA hookup point
76  * @param prefic the prefix to look for
77  *
78  * @return the localized entry or NULL of not found
79  */
80 static struct hna_net *
81 olsr_lookup_hna_net(struct tc_entry *tc, const struct olsr_ip_prefix *prefix)
82 {
83   return (hna_tc_tree2hna(avl_find(&tc->hna_tree, prefix)));
84 }
85
86 /**
87  * Adds a network entry to a HNA gateway.
88  *
89  * @param tc the gateway entry to add the network to
90  * @param net the nework prefix to add
91  * @param prefixlen the prefix length
92  *
93  * @return the newly created entry
94  */
95 static struct hna_net *
96 olsr_add_hna_net(struct tc_entry *tc, const struct olsr_ip_prefix *prefix)
97 {
98   /* Add the net */
99   struct hna_net *new_net = olsr_cookie_malloc(hna_net_mem_cookie);
100
101   /* Fill struct */
102   new_net->hna_prefix = *prefix;
103
104   /* Set backpointer */
105   new_net->hna_tc = tc;
106   olsr_lock_tc_entry(tc);
107
108   /*
109    * Insert into the per-tc hna subtree.
110    */
111   new_net->hna_tc_node.key = &new_net->hna_prefix;
112   avl_insert(&tc->hna_tree, &new_net->hna_tc_node, AVL_DUP_NO);
113
114   return new_net;
115 }
116
117 /**
118  * Delete a single HNA network.
119  *
120  * @param hna_net the hna_net to delete.
121  */
122 static void
123 olsr_delete_hna_net(struct hna_net *hna_net)
124 {
125   struct tc_entry *tc = hna_net->hna_tc;
126
127   /*
128    * Delete the rt_path for the hna_net.
129    */
130   olsr_delete_routing_table(&hna_net->hna_prefix.prefix,
131                             hna_net->hna_prefix.prefix_len,
132                             &tc->addr, OLSR_RT_ORIGIN_HNA);
133
134   /*
135    * Remove from the per-tc tree.
136    */
137   avl_delete(&tc->hna_tree, &hna_net->hna_tc_node);
138
139   /*
140    * Unlock and free.
141    */
142   olsr_unlock_tc_entry(tc);
143   olsr_cookie_free(hna_net_mem_cookie, hna_net);
144 }
145
146 /**
147  * Callback for the hna_net timer.
148  */
149 static void
150 olsr_expire_hna_net_entry(void *context)
151 {
152   struct hna_net *hna_net = context;
153 #if !defined REMOVE_DEBUG
154   struct ipaddr_str buf;
155   struct ipprefix_str prefixstr;
156 #endif
157
158   OLSR_DEBUG(5, "HNA: timeout %s via hna-gw %s\n",
159               olsr_ip_prefix_to_string(&prefixstr, &hna_net->hna_prefix),
160               olsr_ip_to_string(&buf, &hna_net->hna_tc->addr));
161
162   hna_net->hna_net_timer = NULL; /* be pedandic */
163
164   olsr_delete_hna_net(hna_net);
165 }
166
167 /**
168  * Update a HNA entry. If it does not exist it
169  * is created.
170  * This is the only function that should be called
171  * from outside concerning creation of HNA entries.
172  *
173  *@param gw address of the gateway
174  *@param net address of the network
175  *@param mask the netmask
176  *@param vtime the validitytime of the entry
177  *
178  *@return nada
179  */
180 static void
181 olsr_update_hna_entry(const union olsr_ip_addr *gw,
182                       const struct olsr_ip_prefix *prefix,
183                       olsr_reltime vtime)
184 {
185   struct tc_entry *tc = olsr_locate_tc_entry(gw);
186   struct hna_net *net_entry = olsr_lookup_hna_net(tc, prefix);
187
188   if (net_entry == NULL) {
189     /* Need to add the net */
190     net_entry = olsr_add_hna_net(tc, prefix);
191     changes_hna = true;
192   }
193
194   /*
195    * Add the rt_path for the entry.
196    */
197   olsr_insert_routing_table(&net_entry->hna_prefix.prefix,
198                             net_entry->hna_prefix.prefix_len,
199                             &tc->addr,
200                             OLSR_RT_ORIGIN_HNA);
201
202   /*
203    * Start, or refresh the timer, whatever is appropriate.
204    */
205   olsr_set_timer(&net_entry->hna_net_timer, vtime,
206                  OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT,
207                  &olsr_expire_hna_net_entry, net_entry,
208                  hna_net_timer_cookie->ci_id);
209 }
210
211 /**
212  * Print all HNA entries.
213  *
214  *@return nada
215  */
216 void
217 olsr_print_hna_set(void)
218 {
219   /* The whole function doesn't do anything else. */
220 #if !defined REMOVE_INFO
221   struct tc_entry *tc;
222   struct ipaddr_str buf;
223   struct ipprefix_str prefixstr;
224   struct hna_net *hna_net;
225
226   OLSR_INFO(LOG_HNA,
227               "\n--- %s ------------------------------------------------- HNA\n\n",
228               olsr_wallclock_string());
229
230   OLSR_FOR_ALL_TC_ENTRIES(tc) {
231     OLSR_INFO_NH(LOG_HNA, "HNA-gw %s:\n", olsr_ip_to_string(&buf, &tc->addr));
232
233     OLSR_FOR_ALL_TC_HNA_ENTRIES(tc, hna_net) {
234       OLSR_INFO_NH(LOG_HNA, "\t%-27s\n", olsr_ip_prefix_to_string(&prefixstr, &hna_net->hna_prefix));
235     } OLSR_FOR_ALL_TC_HNA_ENTRIES_END(tc, hna_net);
236   } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
237 #endif
238 }
239
240 /**
241  * Process incoming HNA message.
242  * Forwards the message if that is to be done.
243  */
244 bool
245 olsr_input_hna(union olsr_message *msg,
246                struct interface *in_if __attribute__((unused)),
247                union olsr_ip_addr *from_addr)
248 {
249   struct olsrmsg_hdr msg_hdr;
250   struct olsr_ip_prefix prefix;
251   const uint8_t *curr, *curr_end;
252 #if !defined REMOVE_DEBUG
253   struct ipaddr_str buf;
254 #endif
255
256   if (!(curr = olsr_parse_msg_hdr(msg, &msg_hdr))) {
257     return false;
258   }
259
260   /* We are only interested in HNA message types. */
261   if (msg_hdr.type != HNA_MESSAGE) {
262     return false;
263   }
264
265   /*
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.
269    */
270   if (check_neighbor_link(from_addr) != SYM_LINK) {
271     OLSR_DEBUG(LOG_HNA, "Received HNA from NON SYM neighbor %s\n",
272                 olsr_ip_to_string(&buf, from_addr));
273     return false;
274   }
275
276   OLSR_DEBUG(LOG_HNA, "Processing HNA from %s, seq 0x%04x\n",
277               olsr_ip_to_string(&buf, &msg_hdr.originator), msg_hdr.seqno);
278
279   /*
280    * Now walk the list of HNA advertisements.
281    */
282   curr_end = (const uint8_t *)msg + msg_hdr.size;
283   while (curr < curr_end) {
284
285     pkt_get_ipaddress(&curr, &prefix.prefix);
286     pkt_get_prefixlen(&curr, &prefix.prefix_len);
287
288     if (!ip_prefix_list_find(&olsr_cnf->hna_entries, &prefix.prefix,
289                              prefix.prefix_len, olsr_cnf->ip_version)) {
290       /*
291        * Only update if it's not from us.
292        */
293       olsr_update_hna_entry(&msg_hdr.originator, &prefix, msg_hdr.vtime);
294     }
295   }
296   /* Forward the message */
297   return true;
298 }
299
300 /*
301  * Local Variables:
302  * c-basic-offset: 2
303  * indent-tabs-mode: nil
304  * End:
305  */