3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
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.
43 #include "interfaces.h"
45 #include "scheduler.h"
51 #include "socket_parser.h"
54 #include <sys/types.h>
56 #include <net/if_arp.h>
57 #include <netinet/in_systm.h>
58 #include <netinet/ip.h>
59 #include <arpa/inet.h>
63 /* The interface linked-list */
64 struct interface *ifnet;
66 /* Ifchange functions */
68 int (*function) (struct interface *, int);
72 static struct ifchgf *ifchgf_list;
74 /* Some cookies for stats keeping */
75 struct olsr_cookie_info *interface_poll_timer_cookie = NULL;
76 struct olsr_cookie_info *hello_gen_timer_cookie = NULL;
77 struct olsr_cookie_info *tc_gen_timer_cookie = NULL;
78 struct olsr_cookie_info *mid_gen_timer_cookie = NULL;
79 struct olsr_cookie_info *hna_gen_timer_cookie = NULL;
82 *Do initialization of various data needed for
83 *network interface management.
84 *This function also tries to set up the given interfaces.
86 *@return the number of interfaces configured
89 olsr_init_interfacedb(void)
91 struct olsr_if *tmp_if;
97 * Get some cookies for getting stats to ease troubleshooting.
99 interface_poll_timer_cookie = olsr_alloc_cookie("Interface Polling", OLSR_COOKIE_TYPE_TIMER);
101 hello_gen_timer_cookie = olsr_alloc_cookie("Hello Generation", OLSR_COOKIE_TYPE_TIMER);
102 tc_gen_timer_cookie = olsr_alloc_cookie("TC Generation", OLSR_COOKIE_TYPE_TIMER);
103 mid_gen_timer_cookie = olsr_alloc_cookie("MID Generation", OLSR_COOKIE_TYPE_TIMER);
104 hna_gen_timer_cookie = olsr_alloc_cookie("HNA Generation", OLSR_COOKIE_TYPE_TIMER);
106 OLSR_PRINTF(1, "\n ---- Interface configuration ---- \n\n");
107 /* Run trough all interfaces immedeatly */
108 for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) {
109 if (!tmp_if->host_emul) {
110 if (!olsr_cnf->host_emul) /* XXX: TEMPORARY! */
111 chk_if_up(tmp_if, 1);
117 /* Kick a periodic timer for the network interface update function */
118 olsr_start_timer((unsigned int)olsr_cnf->nic_chgs_pollrate * MSEC_PER_SEC, 5, OLSR_TIMER_PERIODIC, &check_interface_updates, NULL,
119 interface_poll_timer_cookie->ci_id);
121 return (ifnet == NULL) ? 0 : 1;
125 olsr_trigger_ifchange(struct interface *ifp, int flag)
127 struct ifchgf *tmp_ifchgf_list = ifchgf_list;
129 while (tmp_ifchgf_list != NULL) {
130 tmp_ifchgf_list->function(ifp, flag);
131 tmp_ifchgf_list = tmp_ifchgf_list->next;
136 *Find the local interface with a given address.
138 *@param addr the address to check.
140 *@return the interface struct representing the interface
141 *that matched the address.
145 if_ifwithaddr(const union olsr_ip_addr *addr)
147 struct interface *ifp;
152 for (ifp = ifnet; ifp; ifp = ifp->int_next) {
153 if (olsr_cnf->ip_version == AF_INET) {
155 //printf("Checking: %s == ", inet_ntoa(((struct sockaddr_in *)&ifp->int_addr)->sin_addr));
156 //printf("%s\n", olsr_ip_to_string(addr));
158 if (((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr == addr->v4.s_addr)
162 //printf("Checking %s ", olsr_ip_to_string((union olsr_ip_addr *)&ifp->int6_addr.sin6_addr));
163 //printf("== %s\n", olsr_ip_to_string((union olsr_ip_addr *)&((struct sockaddr_in6 *)addr)->sin6_addr));
164 if (ip6equal(&ifp->int6_addr.sin6_addr, &addr->v6))
172 *Find the interface with a given number.
174 *@param nr the number of the interface to find.
176 *@return return the interface struct representing the interface
177 *that matched the number.
180 if_ifwithsock(int fd)
182 struct interface *ifp;
186 if (ifp->olsr_socket == fd || ifp->send_socket == fd)
195 *Find the interface with a given label.
197 *@param if_name the label of the interface to find.
199 *@return return the interface struct representing the interface
200 *that matched the label.
203 if_ifwithname(const char *if_name)
205 struct interface *ifp = ifnet;
207 /* good ol' strcmp should be sufficcient here */
208 if (strcmp(ifp->int_name, if_name) == 0) {
217 *Find the interface with a given interface index.
219 *@param iif_index of the interface to find.
221 *@return return the interface struct representing the interface
222 *that matched the iif_index.
225 if_ifwithindex(const int if_index)
227 struct interface *ifp = ifnet;
228 while (ifp != NULL) {
229 if (ifp->if_index == if_index) {
238 *Get an interface name for a given interface index
240 *@param iif_index of the interface to find.
242 *@return "" or interface name.
245 if_ifwithindex_name(const int if_index)
247 const struct interface *const ifp = if_ifwithindex(if_index);
248 return ifp == NULL ? "void" : ifp->int_name;
252 *Create a new interf_name struct using a given
253 *name and insert it into the interface list.
255 *@param name the name of the interface.
260 olsr_create_olsrif(const char *name, int hemu)
262 struct olsr_if *interf_n = olsr_cnf->interfaces;
265 //printf("Adding interface %s\n", name);
267 /* check if the inerfaces already exists */
268 while (interf_n != NULL) {
269 if (strcmp(interf_n->name, name) == 0) {
270 fprintf(stderr, "Duplicate interfaces defined... not adding %s\n", name);
273 interf_n = interf_n->next;
276 interf_n = olsr_malloc(sizeof(struct olsr_if), "queue interface");
278 name_size = strlen(name) + 1;
279 interf_n->name = olsr_malloc(name_size, "queue interface name");
280 strscpy(interf_n->name, name, name_size);
282 interf_n->cnf = olsr_malloc(sizeof(*interf_n->cnf), "queue cnf");
284 interf_n->cnfi = olsr_malloc(sizeof(*interf_n->cnfi), "queue cnfi");
285 memset(interf_n->cnfi, 0xFF, sizeof(*interf_n->cnfi));
286 interf_n->cnfi->orig_lq_mult_cnt=0;
288 interf_n->host_emul = hemu ? true : false;
290 interf_n->next = olsr_cnf->interfaces;
291 olsr_cnf->interfaces = interf_n;
297 *Add an ifchange function. These functions are called on all (non-initial)
298 *changes in the interface set.
305 olsr_add_ifchange_handler(int (*f) (struct interface *, int))
308 struct ifchgf *new_ifchgf;
310 new_ifchgf = olsr_malloc(sizeof(struct ifchgf), "Add ifchgfunction");
312 new_ifchgf->next = ifchgf_list;
313 new_ifchgf->function = f;
315 ifchgf_list = new_ifchgf;
321 * Remove an ifchange function
324 olsr_remove_ifchange_handler(int (*f) (struct interface *, int))
326 struct ifchgf *tmp_ifchgf, *prev;
328 tmp_ifchgf = ifchgf_list;
332 if (tmp_ifchgf->function == f) {
335 ifchgf_list = tmp_ifchgf->next;
338 prev->next = tmp_ifchgf->next;
344 tmp_ifchgf = tmp_ifchgf->next;
351 olsr_remove_interface(struct olsr_if * iface, bool went_down)
353 struct interface *ifp, *tmp_ifp;
357 OLSR_PRINTF(1, "Removing interface %s\n", iface->name);
358 olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
360 olsr_delete_link_entry_by_ip(&ifp->ip_addr);
363 *Call possible ifchange functions registered by plugins
365 olsr_trigger_ifchange(ifp, IFCHG_IF_REMOVE);
367 /*remove all routes*/
369 OLSR_FOR_ALL_RT_ENTRIES(rt) {
370 if (rt->rt_nexthop.iif_index == ifp->if_index) {
371 //marks route as unexisting in kernel, do this better !?
372 rt->rt_nexthop.iif_index=-1;
375 OLSR_FOR_ALL_RT_ENTRIES_END(rt);
380 ifnet = ifp->int_next;
383 while (tmp_ifp->int_next != ifp) {
384 tmp_ifp = tmp_ifp->int_next;
386 tmp_ifp->int_next = ifp->int_next;
389 /* Remove output buffer */
390 net_remove_buffer(ifp);
392 /* Check main addr */
393 /* deactivated to prevent change of originator IP */
395 if (ipequal(&olsr_cnf->main_addr, &ifp->ip_addr)) {
397 /* No more interfaces */
398 memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
399 OLSR_PRINTF(1, "No more interfaces...\n");
401 struct ipaddr_str buf;
402 olsr_cnf->main_addr = ifnet->ip_addr;
403 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
404 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
409 * Deregister functions for periodic message generation
411 olsr_stop_timer(ifp->hello_gen_timer);
412 olsr_stop_timer(ifp->tc_gen_timer);
413 olsr_stop_timer(ifp->mid_gen_timer);
414 olsr_stop_timer(ifp->hna_gen_timer);
416 iface->configured = 0;
417 iface->interf = NULL;
418 /* Close olsr socket */
419 close(ifp->olsr_socket);
420 remove_olsr_socket(ifp->olsr_socket, &olsr_input);
426 if ((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces)) {
427 OLSR_PRINTF(1, "No more active interfaces - exiting.\n");
428 olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
429 olsr_cnf->exit_value = EXIT_FAILURE;
431 kill(getpid(), SIGINT);
441 * indent-tabs-mode: nil