+
/*
* The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas TΓΈnnesen(andreto@olsr.org)
+ * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
* All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
* are met:
*
- * * Redistributions of source code must retain the above copyright
+ * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
* distribution.
- * * Neither the name of olsr.org, olsrd nor the names of its
- * contributors may be used to endorse or promote products derived
+ * * Neither the name of olsr.org, olsrd nor the names of its
+ * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Visit http://www.olsr.org for more information.
* to the project. For more information see the website or contact
* the copyright holders.
*
- * $Id: interfaces.c,v 1.37 2007/11/16 19:12:55 bernd67 Exp $
*/
+#include <signal.h>
+#include <unistd.h>
+
#include "defs.h"
#include "interfaces.h"
#include "ifnet.h"
#include "scheduler.h"
#include "olsr.h"
#include "net_olsr.h"
+#include "ipcalc.h"
+#include "log.h"
+#include "parser.h"
+#include "socket_parser.h"
-static olsr_u32_t if_property_id;
+#ifdef WIN32
+#include <winbase.h>
+#define close(x) closesocket(x)
+#endif
/* The interface linked-list */
struct interface *ifnet;
-/* Datastructures to use when creating new sockets */
-struct sockaddr_in addrsock;
-struct sockaddr_in6 addrsock6;
-
-
/* Ifchange functions */
-struct ifchgf
-{
- int (*function)(struct interface *, int);
+struct ifchgf {
+ int (*function) (struct interface *, enum olsr_ifchg_flag);
struct ifchgf *next;
};
static struct ifchgf *ifchgf_list;
+/* Some cookies for stats keeping */
+struct olsr_cookie_info *interface_poll_timer_cookie = NULL;
+struct olsr_cookie_info *hello_gen_timer_cookie = NULL;
+struct olsr_cookie_info *tc_gen_timer_cookie = NULL;
+struct olsr_cookie_info *mid_gen_timer_cookie = NULL;
+struct olsr_cookie_info *hna_gen_timer_cookie = NULL;
+
/**
*Do initialization of various data needed for
*network interface management.
*@return the number of interfaces configured
*/
int
-ifinit(void)
+olsr_init_interfacedb(void)
{
struct olsr_if *tmp_if;
-
/* Initial values */
ifnet = NULL;
/*
- *Initializing addrsock struct to be
- *used on all the sockets
+ * Get some cookies for getting stats to ease troubleshooting.
*/
- if(olsr_cnf->ip_version == AF_INET)
- {
- /* IP version 4 */
- memset(&addrsock, 0, sizeof (addrsock));
- addrsock.sin_family = AF_INET;
- addrsock.sin_port = htons(OLSRPORT);
- (addrsock.sin_addr).s_addr = INADDR_ANY;
- }
- else
- {
- /* IP version 6 */
- memset(&addrsock6, 0, sizeof (addrsock6));
- addrsock6.sin6_family = AF_INET6;
- addrsock6.sin6_port = htons(OLSRPORT);
- //(addrsock6.sin6_addr).s_addr = IN6ADDR_ANY_INIT;
- }
-
- OLSR_PRINTF(1, "\n ---- Interface configuration ---- \n\n");
- /* Run trough all interfaces immedeatly */
- for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
- {
- if(!tmp_if->host_emul)
- {
- if(!olsr_cnf->host_emul) /* XXX: TEMPORARY! */
- chk_if_up(tmp_if, 1);
- }
- else
- add_hemu_if(tmp_if);
- }
-
- /* register network interface update function with scheduler */
- olsr_register_scheduler_event(&check_interface_updates, NULL,
- olsr_cnf->nic_chgs_pollrate, 0, NULL);
-
- return (ifnet == NULL) ? 0 : 1;
-}
+ interface_poll_timer_cookie = olsr_alloc_cookie("Interface Polling", OLSR_COOKIE_TYPE_TIMER);
+ hello_gen_timer_cookie = olsr_alloc_cookie("Hello Generation", OLSR_COOKIE_TYPE_TIMER);
+ tc_gen_timer_cookie = olsr_alloc_cookie("TC Generation", OLSR_COOKIE_TYPE_TIMER);
+ mid_gen_timer_cookie = olsr_alloc_cookie("MID Generation", OLSR_COOKIE_TYPE_TIMER);
+ hna_gen_timer_cookie = olsr_alloc_cookie("HNA Generation", OLSR_COOKIE_TYPE_TIMER);
-olsr_u32_t
-get_if_property_id(void)
-{
- return if_property_id++;
-}
-
-olsr_bool
-add_if_geninfo(struct interface *ifp, void *data, olsr_u32_t owner_id)
-{
- struct if_gen_property *igp;
-
- if(get_if_geninfo(ifp, owner_id) != NULL)
- return OLSR_FALSE;
-
- igp = olsr_malloc(sizeof(struct if_gen_property), __func__);
-
- igp->owner_id = owner_id;
- igp->data = data;
-
- /* queue */
- igp->next = ifp->gen_properties;
- ifp->gen_properties = igp;
-
- return OLSR_TRUE;
-}
-
-void *
-get_if_geninfo(struct interface *ifp, olsr_u32_t owner_id)
-{
- struct if_gen_property *igp_list = ifp->gen_properties;
-
-
- while(igp_list)
- {
- if(igp_list->owner_id == owner_id)
- return igp_list->data;
-
- igp_list = igp_list->next;
- }
-
- return NULL;
-}
-
-void *
-del_if_geninfo(struct interface *ifp, olsr_u32_t owner_id)
-{
- void *data = NULL;
- struct if_gen_property *igp_list = ifp->gen_properties;
- struct if_gen_property *igp_prev = NULL;
-
-
- while(igp_list)
- {
- if(igp_list->owner_id == owner_id)
- break;
-
- igp_prev = igp_list;
- igp_list = igp_list->next;
+ OLSR_PRINTF(1, "\n ---- Interface configuration ---- \n\n");
+ /* Run trough all interfaces immedeatly */
+ for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) {
+ if (!tmp_if->host_emul) {
+ if (!olsr_cnf->host_emul) /* XXX: TEMPORARY! */
+ chk_if_up(tmp_if, 1);
+ } else {
+ add_hemu_if(tmp_if);
}
+ }
- /* Not found */
- if(igp_list == NULL)
- return NULL;
-
- /* Dequeue */
- if(igp_prev == NULL)
- {
- /* First elem */
- ifp->gen_properties = igp_list->next;
- }
- else
- {
- igp_prev->next = igp_list->next;
- }
- data = igp_list->data;
- free(igp_list);
+ /* Kick a periodic timer for the network interface update function */
+ olsr_start_timer((unsigned int)olsr_cnf->nic_chgs_pollrate * MSEC_PER_SEC, 5, OLSR_TIMER_PERIODIC, &check_interface_updates, NULL,
+ interface_poll_timer_cookie->ci_id);
- return data;
+ return (ifnet == NULL) ? 0 : 1;
}
-
void
-run_ifchg_cbs(struct interface *ifp, int flag)
+olsr_trigger_ifchange(struct interface *ifp, enum olsr_ifchg_flag flag)
{
struct ifchgf *tmp_ifchgf_list = ifchgf_list;
- while(tmp_ifchgf_list != NULL)
- {
- tmp_ifchgf_list->function(ifp, flag);
- tmp_ifchgf_list = tmp_ifchgf_list->next;
- }
+ while (tmp_ifchgf_list != NULL) {
+ tmp_ifchgf_list->function(ifp, flag);
+ tmp_ifchgf_list = tmp_ifchgf_list->next;
+ }
}
-
/**
*Find the local interface with a given address.
*
{
struct interface *ifp;
- if(!addr)
+ if (!addr)
return NULL;
- for (ifp = ifnet; ifp; ifp = ifp->int_next)
- {
- if(olsr_cnf->ip_version == AF_INET)
- {
- /* IPv4 */
- //printf("Checking: %s == ", inet_ntoa(((struct sockaddr_in *)&ifp->int_addr)->sin_addr));
- //printf("%s\n", olsr_ip_to_string(addr));
-
- if (((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr == addr->v4.s_addr)
- return ifp;
- }
- else
- {
- /* IPv6 */
- //printf("Checking %s ", olsr_ip_to_string((union olsr_ip_addr *)&ifp->int6_addr.sin6_addr));
- //printf("== %s\n", olsr_ip_to_string((union olsr_ip_addr *)&((struct sockaddr_in6 *)addr)->sin6_addr));
- if (ip6equal(&ifp->int6_addr.sin6_addr, &addr->v6))
- return ifp;
- }
+ for (ifp = ifnet; ifp; ifp = ifp->int_next) {
+ if (olsr_cnf->ip_version == AF_INET) {
+ /* IPv4 */
+ //printf("Checking: %s == ", inet_ntoa(((struct sockaddr_in *)&ifp->int_addr)->sin_addr));
+ //printf("%s\n", olsr_ip_to_string(addr));
+
+ if (((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr == addr->v4.s_addr)
+ return ifp;
+ } else {
+ /* IPv6 */
+ //printf("Checking %s ", olsr_ip_to_string((union olsr_ip_addr *)&ifp->int6_addr.sin6_addr));
+ //printf("== %s\n", olsr_ip_to_string((union olsr_ip_addr *)&((struct sockaddr_in6 *)addr)->sin6_addr));
+ if (ip6equal(&ifp->int6_addr.sin6_addr, &addr->v6))
+ return ifp;
}
+ }
return NULL;
}
-
-
/**
*Find the interface with a given number.
*
struct interface *ifp;
ifp = ifnet;
- while (ifp)
- {
- if (ifp->olsr_socket == fd)
- return ifp;
- ifp = ifp->int_next;
- }
-
+ while (ifp) {
+ if (ifp->olsr_socket == fd || ifp->send_socket == fd)
+ return ifp;
+ ifp = ifp->int_next;
+ }
+
return NULL;
}
-
/**
*Find the interface with a given label.
*
struct interface *
if_ifwithname(const char *if_name)
{
- struct interface *ifp;
- ifp = ifnet;
-
- while (ifp)
- {
- /* good ol' strcmp should be sufficcient here */
- if (!strcmp(ifp->int_name, if_name))
- return ifp;
- ifp = ifp->int_next;
+ struct interface *ifp = ifnet;
+ while (ifp) {
+ /* good ol' strcmp should be sufficcient here */
+ if (strcmp(ifp->int_name, if_name) == 0) {
+ return ifp;
}
-
+ ifp = ifp->int_next;
+ }
return NULL;
}
+/**
+ *Find the olsr_if with a given label.
+ *
+ *@param if_name the label of the interface to find.
+ *
+ *@return return the interface struct representing the interface
+ *that matched the label.
+ */
+struct olsr_if *
+olsrif_ifwithname(const char *if_name)
+{
+ struct olsr_if *oifp = olsr_cnf->interfaces;
+ while (oifp) {
+ /* good ol' strcmp should be sufficcient here */
+ if (strcmp(oifp->name, if_name) == 0) {
+ return oifp;
+ }
+ oifp = oifp->next;
+ }
+ return NULL;
+}
/**
*Find the interface with a given interface index.
if_ifwithindex(const int if_index)
{
struct interface *ifp = ifnet;
- while (ifp)
- {
- if (ifp->if_index == if_index)
- return ifp;
- ifp = ifp->int_next;
+ while (ifp != NULL) {
+ if (ifp->if_index == if_index) {
+ return ifp;
}
+ ifp = ifp->int_next;
+ }
return NULL;
}
-
/**
*Get an interface name for a given interface index
*
const char *
if_ifwithindex_name(const int if_index)
{
- const struct interface * const ifp = if_ifwithindex(if_index);
+ const struct interface *const ifp = if_ifwithindex(if_index);
return ifp == NULL ? "void" : ifp->int_name;
}
-
/**
*Create a new interf_name struct using a given
*name and insert it into the interface list.
*@return nada
*/
struct olsr_if *
-queue_if(const char *name, int hemu)
+olsr_create_olsrif(const char *name, int hemu)
{
struct olsr_if *interf_n = olsr_cnf->interfaces;
+ size_t name_size;
//printf("Adding interface %s\n", name);
/* check if the inerfaces already exists */
- while(interf_n != NULL)
- {
- if(memcmp(interf_n->name, name, strlen(name)) == 0)
- {
- fprintf(stderr, "Duplicate interfaces defined... not adding %s\n", name);
- return NULL;
- }
- interf_n = interf_n->next;
+ while (interf_n != NULL) {
+ if (strcmp(interf_n->name, name) == 0) {
+ fprintf(stderr, "Duplicate interfaces defined... not adding %s\n", name);
+ return NULL;
}
+ interf_n = interf_n->next;
+ }
interf_n = olsr_malloc(sizeof(struct olsr_if), "queue interface");
- /* strlen () does not return length including terminating /0 */
- interf_n->name = olsr_malloc(strlen(name) + 1, "queue interface name");
- interf_n->cnf = NULL;
- interf_n->interf = NULL;
- interf_n->configured = 0;
+ name_size = strlen(name) + 1;
+ interf_n->name = olsr_malloc(name_size, "queue interface name");
+ strscpy(interf_n->name, name, name_size);
+
+ interf_n->cnf = olsr_malloc(sizeof(*interf_n->cnf), "queue cnf");
- interf_n->host_emul = hemu ? OLSR_TRUE : OLSR_FALSE;
+ interf_n->cnfi = olsr_malloc(sizeof(*interf_n->cnfi), "queue cnfi");
+ memset(interf_n->cnfi, 0xFF, sizeof(*interf_n->cnfi));
+ interf_n->cnfi->orig_lq_mult_cnt=0;
+
+ interf_n->host_emul = hemu ? true : false;
- strncpy(interf_n->name, name, strlen(name) + 1);
interf_n->next = olsr_cnf->interfaces;
olsr_cnf->interfaces = interf_n;
return interf_n;
}
-
-
/**
*Add an ifchange function. These functions are called on all (non-initial)
*changes in the interface set.
*@return
*/
int
-add_ifchgf(int (*f)(struct interface *, int))
+olsr_add_ifchange_handler(int (*f) (struct interface *, enum olsr_ifchg_flag))
{
struct ifchgf *new_ifchgf;
return 1;
}
-
-
/*
* Remove an ifchange function
*/
int
-del_ifchgf(int (*f)(struct interface *, int))
+olsr_remove_ifchange_handler(int (*f) (struct interface *, enum olsr_ifchg_flag))
{
struct ifchgf *tmp_ifchgf, *prev;
tmp_ifchgf = ifchgf_list;
prev = NULL;
- while(tmp_ifchgf)
- {
- if(tmp_ifchgf->function == f)
- {
- /* Remove entry */
- if(prev == NULL)
- {
- ifchgf_list = tmp_ifchgf->next;
- free(tmp_ifchgf);
- }
- else
- {
- prev->next = tmp_ifchgf->next;
- free(tmp_ifchgf);
- }
- return 1;
- }
- prev = tmp_ifchgf;
- tmp_ifchgf = tmp_ifchgf->next;
+ while (tmp_ifchgf) {
+ if (tmp_ifchgf->function == f) {
+ /* Remove entry */
+ if (prev == NULL) {
+ ifchgf_list = tmp_ifchgf->next;
+ free(tmp_ifchgf);
+ } else {
+ prev->next = tmp_ifchgf->next;
+ free(tmp_ifchgf);
+ }
+ return 1;
}
+ prev = tmp_ifchgf;
+ tmp_ifchgf = tmp_ifchgf->next;
+ }
return 0;
}
+
+void
+olsr_remove_interface(struct olsr_if * iface)
+{
+ struct interface *ifp, *tmp_ifp;
+ ifp = iface->interf;
+
+ OLSR_PRINTF(1, "Removing interface %s\n", iface->name);
+ olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
+
+ olsr_delete_link_entry_by_ip(&ifp->ip_addr);
+
+ /*
+ *Call possible ifchange functions registered by plugins
+ */
+ olsr_trigger_ifchange(ifp, IFCHG_IF_REMOVE);
+
+ /* cleanup routes over this interface */
+ olsr_delete_interface_routes(ifp->if_index);
+
+ /* Dequeue */
+ if (ifp == ifnet) {
+ ifnet = ifp->int_next;
+ } else {
+ tmp_ifp = ifnet;
+ while (tmp_ifp->int_next != ifp) {
+ tmp_ifp = tmp_ifp->int_next;
+ }
+ tmp_ifp->int_next = ifp->int_next;
+ }
+
+ /* Remove output buffer */
+ net_remove_buffer(ifp);
+
+ /* Check main addr */
+ /* deactivated to prevent change of originator IP */
+#if 0
+ if (ipequal(&olsr_cnf->main_addr, &ifp->ip_addr)) {
+ if (ifnet == NULL) {
+ /* No more interfaces */
+ memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
+ OLSR_PRINTF(1, "No more interfaces...\n");
+ } else {
+ struct ipaddr_str buf;
+ olsr_cnf->main_addr = ifnet->ip_addr;
+ OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
+ olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
+ }
+ }
+#endif
+ /*
+ * Deregister functions for periodic message generation
+ */
+ olsr_stop_timer(ifp->hello_gen_timer);
+ olsr_stop_timer(ifp->tc_gen_timer);
+ olsr_stop_timer(ifp->mid_gen_timer);
+ olsr_stop_timer(ifp->hna_gen_timer);
+
+ iface->configured = 0;
+ iface->interf = NULL;
+
+ /* Close olsr socket */
+ close(ifp->olsr_socket);
+ remove_olsr_socket(ifp->olsr_socket, &olsr_input);
+
+ if (ifp->send_socket != ifp->olsr_socket) {
+ close(ifp->send_socket);
+ remove_olsr_socket(ifp->send_socket, &olsr_input);
+ }
+
+ /* Free memory */
+ free(ifp->int_name);
+ free(ifp);
+
+ if ((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces)) {
+ olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
+ olsr_exit("No more active interfaces - exiting.\n", EXIT_FAILURE);
+ }
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * End:
+ */