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.
45 #include "mpr_selector_set.h"
48 #include "neighbor_table.h"
49 #include "build_msg.h"
51 #include "lq_plugin.h"
53 static olsr_bool sending_tc = OLSR_FALSE;
56 *Free the memory allocated for a HELLO packet.
58 *@param message the pointer to the packet to erase
63 olsr_free_hello_packet(struct hello_message *message)
65 struct hello_neighbor *nb;
70 nb = message->neighbors;
72 struct hello_neighbor *prev_nb = nb;
79 *Build an internal HELLO package for this
80 *node. This MUST be done for each interface.
82 *@param message the hello_message struct to fill with info
83 *@param outif the interface to send the message on - messages
84 *are created individually for each interface!
88 olsr_build_hello_packet(struct hello_message *message, struct interface *outif)
90 struct hello_neighbor *message_neighbor, *tmp_neigh;
91 struct link_entry *links;
92 struct neighbor_entry *neighbor;
95 OLSR_PRINTF(3, "\tBuilding HELLO on interface \"%s\"\n", outif->int_name ? outif->int_name : "<null>");
98 message->neighbors=NULL;
99 message->packet_seq_number=0;
101 //message->mpr_seq_number=neighbortable.neighbor_mpr_seq;
103 /* Set willingness */
105 message->willingness = olsr_cnf->willingness;
107 OLSR_PRINTF(3, "Willingness: %d\n", olsr_cnf->willingness);
113 message->source_addr = olsr_cnf->main_addr;
116 OLSR_PRINTF(5, "On link:\n");
119 /* Walk all links of this interface */
120 OLSR_FOR_ALL_LINK_ENTRIES(links) {
122 struct ipaddr_str buf;
124 int lnk = lookup_link_status(links);
125 /* Update the status */
127 /* Check if this link tuple is registered on the outgoing interface */
128 if (!ipequal(&links->local_iface_addr, &outif->ip_addr)) {
132 message_neighbor = olsr_malloc_hello_neighbor("Build HELLO");
134 /* Find the link status */
135 message_neighbor->link = lnk;
138 * Calculate neighbor status
141 * 2.1 If the main address, corresponding to
142 * L_neighbor_iface_addr, is included in the MPR set:
144 * Neighbor Type = MPR_NEIGH
146 if (links->neighbor->is_mpr) {
147 message_neighbor->status = MPR_NEIGH;
150 * 2.2 Otherwise, if the main address, corresponding to
151 * L_neighbor_iface_addr, is included in the neighbor set:
155 * It is garanteed to be included when come this far
156 * due to the extentions made in the link sensing
157 * regarding main addresses.
165 * Neighbor Type = SYM_NEIGH
167 if (links->neighbor->status == SYM) {
168 message_neighbor->status = SYM_NEIGH;
173 * Otherwise, if N_status == NOT_SYM
174 * Neighbor Type = NOT_NEIGH
176 else if (links->neighbor->status == NOT_SYM) {
177 message_neighbor->status = NOT_NEIGH;
181 /* Set the remote interface address */
182 message_neighbor->address = links->neighbor_iface_addr;
184 /* Set the main address */
185 message_neighbor->main_address = links->neighbor->neighbor_main_addr;
187 OLSR_PRINTF(5, "Added: %s - status %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
189 message_neighbor->next=message->neighbors;
190 message->neighbors=message_neighbor;
192 } OLSR_FOR_ALL_LINK_ENTRIES_END(links);
197 OLSR_PRINTF(5, "Not on link:\n");
200 /* Add the rest of the neighbors if running on multiple interfaces */
202 if (ifnet != NULL && ifnet->int_next != NULL)
203 OLSR_FOR_ALL_NBR_ENTRIES(neighbor) {
206 struct ipaddr_str buf;
208 /* Check that the neighbor is not added yet */
209 tmp_neigh = message->neighbors;
210 //printf("Checking that the neighbor is not yet added\n");
212 if (ipequal(&tmp_neigh->main_address, &neighbor->neighbor_main_addr)) {
213 //printf("Not adding duplicate neighbor %s\n", olsr_ip_to_string(&neighbor->neighbor_main_addr));
216 tmp_neigh = tmp_neigh->next;
223 message_neighbor = olsr_malloc_hello_neighbor("Build HELLO 2");
225 message_neighbor->link = UNSPEC_LINK;
228 * Calculate neighbor status
231 * 2.1 If the main address, corresponding to
232 * L_neighbor_iface_addr, is included in the MPR set:
234 * Neighbor Type = MPR_NEIGH
236 if (neighbor->is_mpr) {
237 message_neighbor->status = MPR_NEIGH;
240 * 2.2 Otherwise, if the main address, corresponding to
241 * L_neighbor_iface_addr, is included in the neighbor set:
245 * It is garanteed to be included when come this far
246 * due to the extentions made in the link sensing
247 * regarding main addresses.
255 * Neighbor Type = SYM_NEIGH
257 if (neighbor->status == SYM) {
258 message_neighbor->status = SYM_NEIGH;
263 * Otherwise, if N_status == NOT_SYM
264 * Neighbor Type = NOT_NEIGH
266 else if (neighbor->status == NOT_SYM) {
267 message_neighbor->status = NOT_NEIGH;
272 message_neighbor->address = neighbor->neighbor_main_addr;
273 message_neighbor->main_address = neighbor->neighbor_main_addr;
275 OLSR_PRINTF(5, "Added: %s - status %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
277 message_neighbor->next=message->neighbors;
278 message->neighbors=message_neighbor;
280 } OLSR_FOR_ALL_NBR_ENTRIES_END(neighbor);
287 *Free the memory allocated for a TC packet.
289 *@param message the pointer to the packet to erase
294 olsr_free_tc_packet(struct tc_message *message)
296 struct tc_mpr_addr *mprs;
301 mprs = message->multipoint_relay_selector_address;
302 while (mprs != NULL) {
303 struct tc_mpr_addr *prev_mprs = mprs;
310 *Build an internal TC package for this
313 *@param message the tc_message struct to fill with info
317 olsr_build_tc_packet(struct tc_message *message)
319 struct tc_mpr_addr *message_mpr;
320 struct neighbor_entry *entry;
321 olsr_bool entry_added = OLSR_FALSE;
323 message->multipoint_relay_selector_address=NULL;
324 message->packet_seq_number=0;
326 message->hop_count = 0;
327 message->ttl = MAX_TTL;
328 message->ansn = get_local_ansn();
330 message->originator = olsr_cnf->main_addr;
331 message->source_addr = olsr_cnf->main_addr;
334 /* Loop trough all neighbors */
335 OLSR_FOR_ALL_NBR_ENTRIES(entry) {
336 if (entry->status != SYM) {
340 switch (olsr_cnf->tc_redundancy) {
343 /* 2 = Add all neighbors */
344 //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
345 message_mpr = olsr_malloc_tc_mpr_addr("Build TC");
347 message_mpr->address = entry->neighbor_main_addr;
348 message_mpr->next = message->multipoint_relay_selector_address;
349 message->multipoint_relay_selector_address = message_mpr;
350 entry_added = OLSR_TRUE;
355 /* 1 = Add all MPR selectors and selected MPRs */
356 if ((entry->is_mpr) ||
357 (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL)) {
358 //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
359 message_mpr = olsr_malloc_tc_mpr_addr("Build TC 2");
361 message_mpr->address = entry->neighbor_main_addr;
362 message_mpr->next = message->multipoint_relay_selector_address;
363 message->multipoint_relay_selector_address = message_mpr;
364 entry_added = OLSR_TRUE;
370 /* 0 = Add only MPR selectors(default) */
371 if (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL) {
372 //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
373 message_mpr = olsr_malloc_tc_mpr_addr("Build TC 3");
375 message_mpr->address = entry->neighbor_main_addr;
376 message_mpr->next = message->multipoint_relay_selector_address;
377 message->multipoint_relay_selector_address = message_mpr;
378 entry_added = OLSR_TRUE;
384 } OLSR_FOR_ALL_NBR_ENTRIES_END(entry);
387 sending_tc = OLSR_TRUE;
391 OLSR_PRINTF(3, "No more MPR selectors - will send empty TCs\n");
392 set_empty_tc_timer(GET_TIMESTAMP((olsr_cnf->max_tc_vtime*3)*1000));
393 sending_tc = OLSR_FALSE;
401 *Free the memory allocated for a MID packet.
403 *@param message the pointer to the packet to erase
409 olsr_free_mid_packet(struct mid_message *message)
411 struct mid_alias *tmp_adr, *tmp_adr2;
413 tmp_adr = message->mid_addr;
418 tmp_adr = tmp_adr->next;