Merge branch 'master' into interface_cleanup
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Wed, 16 Mar 2016 12:56:49 +0000 (13:56 +0100)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Wed, 16 Mar 2016 12:56:49 +0000 (13:56 +0100)
67 files changed:
CMakeLists.txt
openwrt/oonf-dlep-proxy-git/Makefile
openwrt/oonf-dlep-radio-git/Makefile
openwrt/oonf-olsrd2-git/Makefile
src-api/common/netaddr.c
src-api/common/netaddr.h
src-plugins/CMakeLists.txt
src-plugins/crypto/simple_security/simple_security.c
src-plugins/generic/dlep/dlep_session.c
src-plugins/generic/dlep/dlep_session.h
src-plugins/generic/dlep/ext_base_proto/proto_radio.c
src-plugins/generic/dlep/ext_base_proto/proto_router.c
src-plugins/generic/dlep/router/dlep_router_interface.c
src-plugins/generic/eth_listener/eth_listener.c
src-plugins/generic/layer2info/layer2info.c
src-plugins/generic/link_config/link_config.c
src-plugins/generic/nl80211_listener/nl80211_listener.c
src-plugins/generic/nl80211_listener/nl80211_listener.h
src-plugins/nhdp/auto_ll4/auto_ll4.c
src-plugins/nhdp/constant_metric/constant_metric.c
src-plugins/nhdp/ff_dat_metric/ff_dat_metric.c
src-plugins/nhdp/neighbor_probing/neighbor_probing.c
src-plugins/nhdp/nhdp/nhdp.c
src-plugins/nhdp/nhdp/nhdp_domain.c
src-plugins/nhdp/nhdp/nhdp_interfaces.c
src-plugins/nhdp/nhdp/nhdp_interfaces.h
src-plugins/nhdp/nhdp/nhdp_writer.c
src-plugins/nhdp/nhdpinfo/nhdpinfo.c
src-plugins/olsrv2/olsrv2/olsrv2.c
src-plugins/olsrv2/olsrv2/olsrv2_originator.c
src-plugins/subsystems/CMakeLists.txt
src-plugins/subsystems/oonf_interface.c [deleted file]
src-plugins/subsystems/oonf_interface.h [deleted file]
src-plugins/subsystems/oonf_layer2.c
src-plugins/subsystems/oonf_layer2.h
src-plugins/subsystems/oonf_packet_socket.c
src-plugins/subsystems/oonf_packet_socket.h
src-plugins/subsystems/oonf_rfc5444.c
src-plugins/subsystems/oonf_rfc5444.h
src-plugins/subsystems/oonf_stream_socket.c
src-plugins/subsystems/oonf_stream_socket.h
src-plugins/subsystems/oonf_timer.c
src-plugins/subsystems/os_fd.h
src-plugins/subsystems/os_generic/os_fd_generic_configsocket.c
src-plugins/subsystems/os_generic/os_fd_generic_configsocket.h
src-plugins/subsystems/os_generic/os_fd_generic_getrawsocket.c
src-plugins/subsystems/os_generic/os_fd_generic_getrawsocket.h
src-plugins/subsystems/os_generic/os_fd_generic_getsocket.c
src-plugins/subsystems/os_generic/os_fd_generic_getsocket.h
src-plugins/subsystems/os_generic/os_fd_generic_join_mcast.c
src-plugins/subsystems/os_generic/os_fd_generic_join_mcast.h
src-plugins/subsystems/os_generic/os_interface_generic.c [new file with mode: 0644]
src-plugins/subsystems/os_generic/os_interface_generic.h [new file with mode: 0644]
src-plugins/subsystems/os_generic/os_routing_generic_rt_to_string.c
src-plugins/subsystems/os_interface.h
src-plugins/subsystems/os_linux/os_fd_linux.c
src-plugins/subsystems/os_linux/os_fd_linux.h
src-plugins/subsystems/os_linux/os_interface_linux.c
src-plugins/subsystems/os_linux/os_interface_linux.h
src-plugins/subsystems/os_linux/os_interface_linux_internal.h [moved from src-plugins/subsystems/os_interface_data.h with 62% similarity]
src-plugins/subsystems/os_linux/os_system_linux.c
src-plugins/subsystems/os_linux/os_vif_linux.c
src-plugins/subsystems/os_routing.h
src/dlep-radio/CMakeLists.txt
src/dlep-router/CMakeLists.txt
src/olsrd2-dlep/CMakeLists.txt
src/olsrd2/CMakeLists.txt

index 6a4d99f..567accd 100644 (file)
@@ -1,6 +1,18 @@
 project (OONF C)
 cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
 
+########################################################
+#### Set a default build type if none was specified ####
+########################################################
+
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+  message(STATUS "Setting build type to 'Debug' as none was specified.")
+  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
+  # Set the possible values of build type for cmake-gui
+  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
+    "MinSizeRel" "RelWithDebInfo")
+endif()
+
 ###########################
 #### API configuration ####
 ###########################
index aa3ff78..d2e176f 100644 (file)
@@ -14,7 +14,7 @@ CMAKE_OPTIONS=-D OONF_NO_WERROR:Bool=true \
               -D OONF_NO_TESTING:Bool=true \
               -D UCI:Bool=true \
               -D OONF_APP_DEFAULT_CFG_HANDLER:String=uci \
-              -D OONF_STATIC_PLUGINS:String="class;clock;interface;layer2;packet_socket;socket;stream_socket;telnet;timer;viewer;os_clock;os_fd;os_interface;os_system;nl80211_listener;layer2info;systeminfo;cfg_uciloader;cfg_compact;dlep_proxy" \
+              -D OONF_STATIC_PLUGINS:String="class;clock;layer2;packet_socket;socket;stream_socket;telnet;timer;viewer;os_clock;os_fd;os_interface;os_system;nl80211_listener;layer2info;systeminfo;cfg_uciloader;cfg_compact;dlep_proxy" \
               -D INSTALL_LIB_DIR:Path=lib/oonf \
               -D INSTALL_INCLUDE_DIR:Path=include/oonf \
               -D INSTALL_CMAKE_DIR:Path=lib/oonf \
index 5b04325..02d7daa 100644 (file)
@@ -14,7 +14,7 @@ CMAKE_OPTIONS=-D OONF_NO_WERROR:Bool=true \
               -D OONF_NO_TESTING:Bool=true \
               -D UCI:Bool=true \
               -D OONF_APP_DEFAULT_CFG_HANDLER:String=uci \
-              -D OONF_STATIC_PLUGINS:String="class;clock;interface;layer2;packet_socket;socket;stream_socket;telnet;timer;viewer;os_clock;os_fd;os_interface;os_system;nl80211_listener;layer2info;systeminfo;cfg_uciloader;cfg_compact;dlep_radio" \
+              -D OONF_STATIC_PLUGINS:String="class;clock;layer2;packet_socket;socket;stream_socket;telnet;timer;viewer;os_clock;os_fd;os_interface;os_system;nl80211_listener;layer2info;systeminfo;cfg_uciloader;cfg_compact;dlep_radio" \
               -D INSTALL_LIB_DIR:Path=lib/oonf \
               -D INSTALL_INCLUDE_DIR:Path=include/oonf \
               -D INSTALL_CMAKE_DIR:Path=lib/oonf \
index e1796e3..280aae5 100644 (file)
@@ -14,7 +14,7 @@ CMAKE_OPTIONS=-D OONF_NO_WERROR:Bool=true \
               -D OONF_NO_TESTING:Bool=true \
               -D UCI:Bool=true \
               -D OONF_APP_DEFAULT_CFG_HANDLER:String=uci \
-              -D OONF_STATIC_PLUGINS:String="class;clock;duplicate_set;interface;layer2;packet_socket;rfc5444;socket;stream_socket;telnet;timer;viewer;os_clock;os_fd;os_interface;os_routing;os_system;nhdp;olsrv2;ff_dat_metric;neighbor_probing;nl80211_listener;link_config;layer2info;systeminfo;cfg_uciloader;cfg_compact;nhdpinfo;olsrv2info;netjsoninfo" \
+              -D OONF_STATIC_PLUGINS:String="class;clock;duplicate_set;layer2;packet_socket;rfc5444;socket;stream_socket;telnet;timer;viewer;os_clock;os_fd;os_interface;os_routing;os_system;nhdp;olsrv2;ff_dat_metric;neighbor_probing;nl80211_listener;link_config;layer2info;systeminfo;cfg_uciloader;cfg_compact;nhdpinfo;olsrv2info;netjsoninfo" \
               -D INSTALL_LIB_DIR:Path=lib/oonf \
               -D INSTALL_INCLUDE_DIR:Path=include/oonf \
               -D INSTALL_CMAKE_DIR:Path=lib/oonf \
index 5ffb073..1ee9b55 100644 (file)
@@ -94,6 +94,9 @@ const struct netaddr NETADDR_IPV6_LINKLOCAL = { { 0xfe,0x80,0,0,0,0,0,0,0,0,0,0,
 /*! IPv6 unique local prefix */
 const struct netaddr NETADDR_IPV6_ULA = { { 0xfc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, AF_INET6, 7 };
 
+/*! IPv6 routable prefix */
+const struct netaddr NETADDR_IPV6_GLOBAL = { { 0x20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, AF_INET6, 3 };
+
 /*! IPv6 ipv4-compatible prefix */
 const struct netaddr NETADDR_IPV6_IPV4COMPATIBLE = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, AF_INET6, 96 };
 
index a8eda2c..17d63b7 100644 (file)
@@ -163,6 +163,7 @@ EXPORT extern const struct netaddr NETADDR_IPV6_BINDTO_ANY;
 EXPORT extern const struct netaddr NETADDR_IPV6_MULTICAST;
 EXPORT extern const struct netaddr NETADDR_IPV6_LINKLOCAL;
 EXPORT extern const struct netaddr NETADDR_IPV6_ULA;
+EXPORT extern const struct netaddr NETADDR_IPV6_GLOBAL;
 EXPORT extern const struct netaddr NETADDR_IPV6_IPV4COMPATIBLE;
 EXPORT extern const struct netaddr NETADDR_IPV6_IPV4MAPPED;
 EXPORT extern const struct netaddr NETADDR_IPV6_LOOPBACK;
index fbd2ffc..93937c3 100644 (file)
@@ -6,7 +6,7 @@ include_directories(nhdp)
 include_directories(olsrv2)
 
 # add subdirectories
-add_subdirectory(crypto)
+#add_subdirectory(crypto)
 add_subdirectory(generic)
 add_subdirectory(nhdp)
 add_subdirectory(olsrv2)
index 1600820..204ba07 100644 (file)
@@ -400,7 +400,7 @@ _cb_query_trigger(void *ptr) {
 static enum rfc5444_result
 _cb_timestamp_tlv(struct rfc5444_reader_tlvblock_context *context __attribute__((unused))) {
   struct oonf_rfc5444_target *target;
-  struct os_interface *core_if;
+  struct os_interface_listener *core_if;
   struct neighbor_node *node;
   uint32_t timestamp, query, response;
   enum rfc5444_result result;
@@ -411,7 +411,7 @@ _cb_timestamp_tlv(struct rfc5444_reader_tlvblock_context *context __attribute__(
 
   struct neighbor_key key;
 
-  core_if = oonf_rfc5444_get_core_interface(_protocol->input_interface);
+  core_if = oonf_rfc5444_get_core_if_listener(_protocol->input_interface);
 
   /* get input-addr/interface combination */
   memset(&key, 0, sizeof(key));
@@ -537,7 +537,7 @@ _cb_timestamp_failed(struct rfc5444_reader_tlvblock_context *context __attribute
 static void
 _cb_addPacketTLVs(struct rfc5444_writer *writer, struct rfc5444_writer_target *rfc5444_target) {
   struct oonf_rfc5444_target *target;
-  struct os_interface *core_if;
+  struct os_interface_listener *core_if;
   struct neighbor_node *node;
   uint32_t query, response;
 #ifdef OONF_LOG_DEBUG_INFO
@@ -550,7 +550,7 @@ _cb_addPacketTLVs(struct rfc5444_writer *writer, struct rfc5444_writer_target *r
   target = oonf_rfc5444_get_target_from_rfc5444_target(rfc5444_target);
 
   /* get core interface */
-  core_if = oonf_rfc5444_get_core_interface(target->interface);
+  core_if = oonf_rfc5444_get_core_if_listener(target->interface);
 
   /* get input-addr/interface combination */
   memset(&key, 0, sizeof(key));
index 394ee98..548449b 100644 (file)
@@ -139,7 +139,7 @@ dlep_session_add(struct dlep_session *session, const char *l2_ifname,
   session->l2_listener.name = l2_ifname;
 
   /* get interface listener to lock interface */
-  if ((oonf_interface_add_listener(&session->l2_listener))) {
+  if ((os_interface_add(&session->l2_listener))) {
     OONF_WARN(session->log_source,
         "Cannot activate interface listener for %s", l2_ifname);
     dlep_session_remove(session);
@@ -202,7 +202,7 @@ dlep_session_remove(struct dlep_session *session) {
       session->l2_listener.name,
       netaddr_socket_to_string(&nbuf, &session->remote_socket));
 
-  oonf_interface_remove_listener(&session->l2_listener);
+  os_interface_remove(&session->l2_listener);
 
   parser = &session->parser;
   avl_for_each_element_safe(&parser->allowed_tlvs, tlv, _node, tlv_it) {
index 06913c2..ad87ab6 100644 (file)
@@ -54,10 +54,9 @@ struct dlep_writer;
 #include "common/autobuf.h"
 #include "common/netaddr.h"
 #include "subsystems/oonf_layer2.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_stream_socket.h"
 #include "subsystems/oonf_timer.h"
-#include "subsystems/os_interface_data.h"
+#include "subsystems/os_interface.h"
 
 #include "dlep/dlep_extension.h"
 #include "dlep/dlep_iana.h"
@@ -285,7 +284,7 @@ struct dlep_session {
   enum oonf_log_source log_source;
 
   /*! local layer2 data interface */
-  struct oonf_interface_listener l2_listener;
+  struct os_interface_listener l2_listener;
 
   /*! timer to generate discovery/heartbeats */
   struct oonf_timer_instance local_event_timer;
index eec73c3..9ed0b7b 100644 (file)
@@ -496,7 +496,7 @@ _radio_write_peer_offer(
   struct netaddr local_addr;
 
   radio_if = dlep_radio_get_by_layer2_if(
-      session->l2_listener.interface->data.name);
+      session->l2_listener.data->name);
   if (!radio_if || &radio_if->interf.session != session) {
     /* unknown type of session, ignore */
     return 0;
index e91101b..b3cae65 100644 (file)
@@ -261,7 +261,7 @@ _router_process_peer_offer(
   struct netaddr addr;
   uint16_t port;
   bool tls;
-  struct os_interface_data *ifdata;
+  struct os_interface *ifdata;
 
   if (session->restrict_signal != DLEP_PEER_OFFER) {
     /* ignore unless we are in discovery mode */
@@ -275,7 +275,7 @@ _router_process_peer_offer(
   result = NULL;
 
   /* remember interface data */
-  ifdata = &session->l2_listener.interface->data;
+  ifdata = session->l2_listener.data;
 
   /* IPv6 offer */
   value = dlep_session_get_tlv_value(session, DLEP_IPV6_CONPOINT_TLV);
@@ -290,7 +290,7 @@ _router_process_peer_offer(
     }
     else if (netaddr_is_in_subnet(&NETADDR_IPV6_LINKLOCAL, &addr)
         || result == NULL) {
-      result = oonf_interface_get_prefix_from_dst(&addr, ifdata);
+      result = os_interface_get_prefix_from_dst(&addr, ifdata);
       if (result) {
         netaddr_socket_init(&remote, &addr, port, ifdata->index);
       }
@@ -309,7 +309,7 @@ _router_process_peer_offer(
       /* TLS not supported at the moment */
     }
     else {
-      result = oonf_interface_get_prefix_from_dst(&addr, ifdata);
+      result = os_interface_get_prefix_from_dst(&addr, ifdata);
       if (result) {
         netaddr_socket_init(&remote, &addr, port, ifdata->index);
       }
@@ -320,7 +320,7 @@ _router_process_peer_offer(
   /* remote address of incoming session */
   if (!result) {
     netaddr_from_socket(&addr, &session->remote_socket);
-    result = oonf_interface_get_prefix_from_dst(&addr, ifdata);
+    result = os_interface_get_prefix_from_dst(&addr, ifdata);
     if (!result) {
       /* no possible way to communicate */
       OONF_DEBUG(session->log_source,
index 8cd23f4..e5d575b 100644 (file)
@@ -210,7 +210,7 @@ dlep_router_remove_interface(struct dlep_router_if *interface) {
 void
 dlep_router_apply_interface_settings(struct dlep_router_if *interf) {
   struct dlep_extension *ext;
-  struct os_interface_data *ifdata;
+  struct os_interface *os_if;
   const struct netaddr *result;
   union netaddr_socket local, remote;
 #ifdef OONF_LOG_DEBUG_INFO
@@ -222,18 +222,18 @@ dlep_router_apply_interface_settings(struct dlep_router_if *interf) {
   _cleanup_interface(interf);
 
   if (!netaddr_is_unspec(&interf->connect_to_addr)) {
-    ifdata = &interf->interf.session.l2_listener.interface->data;
+    os_if = interf->interf.session.l2_listener.data;
 
     OONF_DEBUG(LOG_DLEP_ROUTER, "Connect directly to [%s]:%d",
         netaddr_to_string(&nbuf, &interf->connect_to_addr),
         interf->connect_to_port);
 
-    result = oonf_interface_get_prefix_from_dst(&interf->connect_to_addr, ifdata);
+    result = os_interface_get_prefix_from_dst(&interf->connect_to_addr, os_if);
     if (result) {
       /* initialize local and remote socket */
-      netaddr_socket_init(&local, result, 0, ifdata->index);
+      netaddr_socket_init(&local, result, 0, os_if->index);
       netaddr_socket_init(&remote,
-          &interf->connect_to_addr, interf->connect_to_port, ifdata->index);
+          &interf->connect_to_addr, interf->connect_to_port, os_if->index);
 
       dlep_router_add_session(interf, &local, &remote);
     }
index 9d3ae73..ec6f0ca 100644 (file)
@@ -55,9 +55,9 @@
 #include "config/cfg_schema.h"
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_clock.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_layer2.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 
 #include "eth_listener/eth_listener.h"
 #include "eth_listener/ethtool-copy.h"
@@ -98,9 +98,9 @@ static struct _eth_config _config;
 /* plugin declaration */
 static const char *_dependencies[] = {
   OONF_CLOCK_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_LAYER2_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
 };
 static struct oonf_subsystem _eth_listener_subsystem = {
   .name = OONF_ETH_LISTENER_SUBSYSTEM,
@@ -161,7 +161,7 @@ _cleanup(void) {
 static void
 _cb_transmission_event(struct oonf_timer_instance *ptr __attribute((unused))) {
   struct oonf_layer2_net *l2net;
-  struct os_interface *interf;
+  struct os_interface *os_if;
   struct ethtool_cmd cmd;
   struct ifreq req;
   int64_t ethspeed;
@@ -170,7 +170,7 @@ _cb_transmission_event(struct oonf_timer_instance *ptr __attribute((unused))) {
   struct isonumber_str ibuf;
 #endif
 
-  avl_for_each_element(oonf_interface_get_tree(), interf, _node) {
+  avl_for_each_element(os_interface_get_tree(), os_if, _node) {
     /* initialize ethtool command */
     memset(&cmd, 0, sizeof(cmd));
     cmd.cmd = ETHTOOL_GSET;
@@ -179,17 +179,17 @@ _cb_transmission_event(struct oonf_timer_instance *ptr __attribute((unused))) {
     memset(&req, 0, sizeof(req));
     req.ifr_data = (void *)&cmd;
 
-    if (interf->data.base_index != interf->data.index) {
+    if (os_if->base_index != os_if->index) {
       /* get name of base interface */
-      if (if_indextoname(interf->data.base_index, req.ifr_name) == NULL) {
+      if (if_indextoname(os_if->base_index, req.ifr_name) == NULL) {
         OONF_WARN(LOG_ETH, "Could not get interface name of index %u: %s (%d)",
-            interf->data.base_index, strerror(errno), errno);
+            os_if->base_index, strerror(errno), errno);
         continue;
       }
     }
     else {
       /* copy interface name directly */
-      strscpy(req.ifr_name, interf->data.name, IF_NAMESIZE);
+      strscpy(req.ifr_name, os_if->name, IF_NAMESIZE);
     }
 
     /* request ethernet information from kernel */
@@ -199,7 +199,7 @@ _cb_transmission_event(struct oonf_timer_instance *ptr __attribute((unused))) {
     }
 
     /* layer-2 object for this interface */
-    l2net = oonf_layer2_net_add(interf->data.name);
+    l2net = oonf_layer2_net_add(os_if->name);
     if (l2net == NULL) {
       continue;
     }
@@ -213,7 +213,8 @@ _cb_transmission_event(struct oonf_timer_instance *ptr __attribute((unused))) {
 
     /* set corresponding database entries */
     OONF_DEBUG(LOG_ETH, "Set default link speed of interface %s to %s",
-        interf->data.name, isonumber_from_s64(&ibuf, ethspeed, "bit/s", 0, false, false));
+        os_if->name,
+        isonumber_from_s64(&ibuf, ethspeed, "bit/s", 0, false, false));
 
     oonf_layer2_set_value(&l2net->neighdata[OONF_LAYER2_NEIGH_RX_BITRATE],
         _l2_origin, ethspeed);
index d8a25a9..453157a 100644 (file)
@@ -328,14 +328,14 @@ _cb_layer2info_help(struct oonf_telnet_data *con) {
  */
 static void
 _initialize_interface_values(struct oonf_layer2_net *net) {
-  struct os_interface_data *data;
+  struct os_interface *os_if;
 
-  data = &net->if_listener.interface->data;
+  os_if = net->if_listener.data;
 
   strscpy(_value_if, net->name, sizeof(_value_if));
-  snprintf(_value_if_index, sizeof(_value_if_index), "%u", data->index);
+  snprintf(_value_if_index, sizeof(_value_if_index), "%u", os_if->index);
   strscpy(_value_if_ident, net->if_ident, sizeof(_value_if_ident));
-  netaddr_to_string(&_value_if_local_addr, &data->mac);
+  netaddr_to_string(&_value_if_local_addr, &os_if->mac);
 
   if (net->last_seen) {
     oonf_clock_toIntervalString(&_value_if_lastseen,
index 3fdad89..1fd7f08 100644 (file)
@@ -51,8 +51,8 @@
 #include "core/oonf_logging.h"
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_layer2.h"
+#include "subsystems/os_interface.h"
 
 #include "link_config/link_config.h"
 
@@ -103,8 +103,8 @@ static struct cfg_schema_section _link_config_section = {
 /* declare subsystem */
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_LAYER2_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
 };
 static struct oonf_subsystem _oonf_link_config_subsystem = {
   .name = OONF_LINK_CONFIG_SUBSYSTEM,
index dcbe7c5..728f43a 100644 (file)
@@ -70,9 +70,9 @@
 #include "core/oonf_logging.h"
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_layer2.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 #include "subsystems/os_system.h"
 
 #include "nl80211_listener/genl_get_family.h"
@@ -224,9 +224,9 @@ static struct _nl80211_config _config;
 /* plugin declaration */
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_LAYER2_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
   OONF_OS_SYSTEM_SUBSYSTEM,
 };
 
@@ -449,7 +449,7 @@ _nl80211_if_add(const char *name) {
 
   /* initialize interface listener */
   interf->if_listener.name = interf->name;
-  if (oonf_interface_add_listener(&interf->if_listener)) {
+  if (os_interface_add(&interf->if_listener)) {
     oonf_layer2_net_remove(interf->l2net, _layer2_origin);
     oonf_class_free(&_nl80211_if_class, interf);
     return NULL;
@@ -470,7 +470,7 @@ _nl80211_if_add(const char *name) {
 static void
 _nl80211_if_remove(struct nl80211_if *interf) {
   avl_remove(&_nl80211_if_tree, &interf->_node);
-  oonf_interface_remove_listener(&interf->if_listener);
+  os_interface_remove(&interf->if_listener);
   oonf_class_free(&_nl80211_if_class, interf);
 }
 
index 84106c8..91e11f7 100644 (file)
@@ -48,8 +48,8 @@
 
 #include "common/common_types.h"
 #include "core/oonf_subsystem.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_layer2.h"
+#include "subsystems/os_interface.h"
 
 /*! subsystem identifier */
 #define OONF_NL80211_LISTENER_SUBSYSTEM "nl80211_listener"
@@ -62,7 +62,7 @@ struct nl80211_if {
   char name[IF_NAMESIZE];
 
   /*! interface listener */
-  struct oonf_interface_listener if_listener;
+  struct os_interface_listener if_listener;
 
   /*! layer2 network object of interface */
   struct oonf_layer2_net *l2net;
@@ -108,7 +108,7 @@ bool nl80211_change_l2neigh_data(struct oonf_layer2_neigh *l2neigh,
  */
 static INLINE unsigned
 nl80211_get_if_index(struct nl80211_if *interf) {
-  return interf->if_listener.interface->data.index;
+  return interf->if_listener.data->index;
 }
 
 #endif /* NL80211_LISTENER_H_ */
index bb2e102..c6c3c24 100644 (file)
@@ -55,7 +55,6 @@
 #include "core/oonf_subsystem.h"
 #include "core/os_core.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_timer.h"
 #include "subsystems/os_interface.h"
 
@@ -93,7 +92,7 @@ struct _nhdp_if_autoll4 {
   bool plugin_generated;
 
   /*! data structure for setting and resetting auto-configured address */
-  struct os_interface_address os_addr;
+  struct os_interface_ip_change os_addr;
 
   /*! currently configured address */
   struct netaddr auto_ll4_addr;
@@ -106,10 +105,10 @@ static void _cleanup(void);
 
 static void _cb_add_nhdp_interface(void *);
 static void _cb_remove_nhdp_interface(void *);
-static void _cb_address_finished(struct os_interface_address *, int);
+static void _cb_address_finished(struct os_interface_ip_change *, int);
 static void _cb_update_timer(struct oonf_timer_instance *);
 static int _get_current_if_ipv4_addresscount(
-    struct os_interface_data *ifdata,
+    struct os_interface *os_if,
     struct netaddr *ll4_addr, struct netaddr *current_ll4);
 static void _generate_default_address(
     struct _nhdp_if_autoll4 *auto_ll4, const struct netaddr *ipv6_ll);
@@ -158,7 +157,6 @@ static struct cfg_schema_section _auto_ll4_section = {
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_OS_INTERFACE_SUBSYSTEM,
   OONF_NHDP_SUBSYSTEM,
 };
@@ -251,7 +249,7 @@ _initiate_shutdown(void) {
 
   avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
     OONF_DEBUG(LOG_AUTO_LL4, "initiate cleanup if: %s",
-        nhdp_interface_get_coreif(nhdp_if)->data.name);
+        nhdp_interface_get_if_listener(nhdp_if)->data->name);
     _cb_remove_nhdp_interface(nhdp_if);
   }
   oonf_class_extension_remove(&_nhdp_if_extenstion);
@@ -283,7 +281,7 @@ _cb_add_nhdp_interface(void *ptr) {
 
   /* initialize static part of routing data */
   auto_ll4->os_addr.cb_finished = _cb_address_finished;
-  auto_ll4->os_addr.if_index = nhdp_interface_get_coreif(nhdp_if)->data.index;
+  auto_ll4->os_addr.if_index = nhdp_interface_get_if_listener(nhdp_if)->data->index;
   auto_ll4->os_addr.scope = OS_ADDR_SCOPE_LINK;
 
 
@@ -323,7 +321,7 @@ _cb_remove_nhdp_interface(void *ptr) {
  * @param error 0 if address was set, otherwise an error happened
  */
 static void
-_cb_address_finished(struct os_interface_address *os_addr, int error) {
+_cb_address_finished(struct os_interface_ip_change *os_addr, int error) {
   struct _nhdp_if_autoll4 *auto_ll4;
 #ifdef OONF_LOG_DEBUG_INFO
   struct netaddr_str nbuf;
@@ -438,7 +436,7 @@ _cb_2hop_change(void *ptr) {
 static void
 _cb_update_timer(struct oonf_timer_instance *ptr) {
   struct nhdp_interface *nhdp_if;
-  struct os_interface_data *ifdata;
+  struct os_interface *os_if;
   struct _nhdp_if_autoll4 *auto_ll4;
   struct netaddr current_ll4;
   int count;
@@ -452,17 +450,17 @@ _cb_update_timer(struct oonf_timer_instance *ptr) {
   nhdp_if = auto_ll4->nhdp_if;
 
   /* get pointer to interface data */
-  ifdata = &(nhdp_interface_get_coreif(nhdp_if)->data);
+  os_if = nhdp_interface_get_if_listener(nhdp_if)->data;
 
   /* ignore loopback */
-  if (ifdata->loopback || !ifdata->up) {
+  if (os_if->if_type == OS_IFTYPE_LOOPBACK || !os_if->up) {
     OONF_DEBUG(LOG_AUTO_LL4, "Ignore interface %s: its loopback or down",
-        ifdata->name);
+        os_if->name);
     return;
   }
 
   /* query current interface status */
-  count = _get_current_if_ipv4_addresscount(ifdata, &current_ll4, &auto_ll4->auto_ll4_addr);
+  count = _get_current_if_ipv4_addresscount(os_if, &current_ll4, &auto_ll4->auto_ll4_addr);
 
   if (!oonf_rfc5444_is_interface_active(nhdp_if->rfc5444_if.interface, AF_INET6)) {
     if (auto_ll4->plugin_generated) {
@@ -472,7 +470,7 @@ _cb_update_timer(struct oonf_timer_instance *ptr) {
           "Remove LL4 address, interface is not using NHDP on IPv6");
     }
     OONF_DEBUG(LOG_AUTO_LL4,
-        "Done (interface %s is not using NHDP on IPv6)", ifdata->name);
+        "Done (interface %s is not using NHDP on IPv6)", os_if->name);
     return;
   }
 
@@ -483,7 +481,7 @@ _cb_update_timer(struct oonf_timer_instance *ptr) {
       _commit_address(auto_ll4, &current_ll4, false);
       OONF_DEBUG(LOG_AUTO_LL4, "Remove LL4, user has selected his own address");
     }
-    OONF_DEBUG(LOG_AUTO_LL4, "Done (interface %s is not active)", ifdata->name);
+    OONF_DEBUG(LOG_AUTO_LL4, "Done (interface %s is not active)", os_if->name);
     return;
   }
 
@@ -494,14 +492,14 @@ _cb_update_timer(struct oonf_timer_instance *ptr) {
       _commit_address(auto_ll4, &current_ll4, false);
       OONF_DEBUG(LOG_AUTO_LL4, "Remove LL4, user has selected his own address");
     }
-    OONF_DEBUG(LOG_AUTO_LL4, "Done (interface %s has additional addresses)", ifdata->name);
+    OONF_DEBUG(LOG_AUTO_LL4, "Done (interface %s has additional addresses)", os_if->name);
     return;
   }
 
   if (count == 1) {
     if (netaddr_get_address_family(&current_ll4) == AF_UNSPEC) {
       /* do nothing, user set a non-LL interface IP */
-      OONF_DEBUG(LOG_AUTO_LL4, "Done (interface %s has non-ll ipv4)", ifdata->name);
+      OONF_DEBUG(LOG_AUTO_LL4, "Done (interface %s has non-ll ipv4)", os_if->name);
       return;
     }
 
@@ -511,7 +509,7 @@ _cb_update_timer(struct oonf_timer_instance *ptr) {
 
   if (netaddr_get_address_family(&auto_ll4->auto_ll4_addr) == AF_UNSPEC) {
     /* try our default IP first */
-    _generate_default_address(auto_ll4, ifdata->linklocal_v6_ptr);
+    _generate_default_address(auto_ll4, os_if->if_linklocal_v6);
   }
 
   while (_nhdp_if_has_collision(nhdp_if, &auto_ll4->auto_ll4_addr)) {
@@ -528,7 +526,7 @@ _cb_update_timer(struct oonf_timer_instance *ptr) {
   if (netaddr_cmp(&auto_ll4->auto_ll4_addr, &current_ll4) == 0) {
     /* nothing to do */
     OONF_DEBUG(LOG_AUTO_LL4, "Done (interface %s already has ll %s)",
-        ifdata->name, netaddr_to_string(&nbuf, &current_ll4));
+        os_if->name, netaddr_to_string(&nbuf, &current_ll4));
     return;
   }
 
@@ -586,12 +584,11 @@ _generate_default_address(struct _nhdp_if_autoll4 *auto_ll4, const struct netadd
  * @return number of IPv4 addresses on interface
  */
 static int
-_get_current_if_ipv4_addresscount(struct os_interface_data *ifdata,
+_get_current_if_ipv4_addresscount(struct os_interface *os_if,
     struct netaddr *ll4_addr, struct netaddr *current_ll4) {
-  struct netaddr *ifaddr;
+  struct os_interface_ip *ip;
   bool match;
   int count;
-  size_t i;
 #ifdef OONF_LOG_DEBUG_INFO
   struct netaddr_str nbuf;
 #endif
@@ -601,22 +598,20 @@ _get_current_if_ipv4_addresscount(struct os_interface_data *ifdata,
   netaddr_invalidate(ll4_addr);
   match = false;
 
-  for (i=0; i<ifdata->addrcount; i++) {
-    /* look through interface IPs */
-    ifaddr = &ifdata->addresses[i];
-
+  avl_for_each_element(&os_if->addresses, ip, _node) {
     OONF_DEBUG(LOG_AUTO_LL4, "Interface %s has address %s",
-        ifdata->name, netaddr_to_string(&nbuf, ifaddr));
+        os_if->name, netaddr_to_string(&nbuf, &ip->address));
 
-    if (netaddr_get_address_family(ifaddr) == AF_INET) {
+    if (netaddr_get_address_family(&ip->address) == AF_INET) {
       /* count IPv4 addresses */
       count++;
 
       /* copy one IPv4 link-local address, if possible the current one */
-      if (!match && netaddr_is_in_subnet(&NETADDR_IPV4_LINKLOCAL, ifaddr)) {
-        memcpy(ll4_addr, &ifdata->addresses[i], sizeof(*ll4_addr));
+      if (!match
+          && netaddr_is_in_subnet(&NETADDR_IPV4_LINKLOCAL, &ip->address)) {
+        memcpy(ll4_addr, &ip->address, sizeof(*ll4_addr));
 
-        if (netaddr_cmp(ifaddr, current_ll4) == 0) {
+        if (netaddr_cmp(&ip->address, current_ll4) == 0) {
           match = true;
         }
       }
index 22dba46..c8bbc7c 100644 (file)
@@ -56,9 +56,9 @@
 #include "core/oonf_logging.h"
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_rfc5444.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 
 #include "nhdp/nhdp.h"
 #include "nhdp/nhdp_domain.h"
@@ -110,7 +110,7 @@ static struct cfg_schema_entry _constant_entries[] = {
 static struct cfg_schema_section _constant_section = {
   .type = OONF_CONSTANT_METRIC_SUBSYSTEM,
   .mode = CFG_SSMODE_NAMED_WITH_DEFAULT,
-  .def_name = OONF_INTERFACE_WILDCARD,
+  .def_name = OS_INTERFACE_ANY,
   .cb_delta_handler = _cb_cfg_changed,
   .entries = _constant_entries,
   .entry_count = ARRAYSIZE(_constant_entries),
@@ -118,8 +118,8 @@ static struct cfg_schema_section _constant_section = {
 
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
   OONF_NHDP_SUBSYSTEM,
 };
 static struct oonf_subsystem _olsrv2_constant_metric_subsystem = {
@@ -265,17 +265,17 @@ _cb_set_linkcost(struct oonf_timer_instance *ptr __attribute__((unused))) {
       entry = _get_linkcost(ifname, &lnk->dualstack_partner->neigh->originator);
     }
     if (entry == NULL) {
-      entry = _get_linkcost(OONF_INTERFACE_WILDCARD, &lnk->neigh->originator);
+      entry = _get_linkcost(OS_INTERFACE_ANY, &lnk->neigh->originator);
     }
     if (entry == NULL && nhdp_db_link_is_dualstack(lnk)) {
-      entry = _get_linkcost(OONF_INTERFACE_WILDCARD,
+      entry = _get_linkcost(OS_INTERFACE_ANY,
           &lnk->dualstack_partner->neigh->originator);
     }
     if (entry == NULL)  {
       entry = _get_linkcost(ifname, &NETADDR_UNSPEC);
     }
     if (entry == NULL) {
-      entry = _get_linkcost(OONF_INTERFACE_WILDCARD, &NETADDR_UNSPEC);
+      entry = _get_linkcost(OS_INTERFACE_ANY, &NETADDR_UNSPEC);
     }
     if (entry) {
       OONF_DEBUG(LOG_CONSTANT_METRIC, "Found metric value %u", entry->cost);
index c80ade3..e36574b 100644 (file)
@@ -514,8 +514,7 @@ _get_median_rx_linkspeed(struct link_datff_data *ldata) {
  */
 static int
 _get_scaled_rx_linkspeed(struct nhdp_link *lnk) {
-  // const struct oonf_linkconfig_data *linkdata;
-  struct os_interface_data *ifdata;
+  struct os_interface *os_if;
   const struct oonf_layer2_data *l2data;
   int rate;
 
@@ -525,13 +524,10 @@ _get_scaled_rx_linkspeed(struct nhdp_link *lnk) {
   }
 
   /* get local interface data  */
-  ifdata = oonf_interface_get_data(nhdp_interface_get_name(lnk->local_if), NULL);
-  if (!ifdata) {
-    return 1;
-  }
+  os_if = nhdp_interface_get_if_listener(lnk->local_if)->data;
 
   l2data = oonf_layer2_neigh_query(
-      ifdata->name, &lnk->remote_mac, OONF_LAYER2_NEIGH_RX_BITRATE);
+      os_if->name, &lnk->remote_mac, OONF_LAYER2_NEIGH_RX_BITRATE);
   if (!l2data) {
     return 1;
   }
index 15a16cb..bf9e8af 100644 (file)
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_class.h"
 #include "subsystems/oonf_clock.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_layer2.h"
 #include "subsystems/oonf_rfc5444.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 
 #include "nhdp/nhdp_db.h"
 #include "nhdp/nhdp_interfaces.h"
@@ -128,10 +128,10 @@ static struct cfg_schema_section _probing_section = {
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
   OONF_CLOCK_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_LAYER2_SUBSYSTEM,
   OONF_RFC5444_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
   OONF_NHDP_SUBSYSTEM,
 };
 static struct oonf_subsystem _olsrv2_neighbor_probing_subsystem = {
@@ -263,9 +263,9 @@ static void
 _cb_probe_link(struct oonf_timer_instance *ptr __attribute__((unused))) {
   struct nhdp_link *lnk, *best_lnk;
   struct _probing_link_data *ldata, *best_ldata;
-  struct nhdp_interface *ninterf;
+  struct nhdp_interface *nhdp_if;
 
-  struct os_interface *interf;
+  struct os_interface_listener *if_listener;
   struct oonf_layer2_net *l2net;
   struct oonf_layer2_neigh *l2neigh;
 
@@ -283,24 +283,24 @@ _cb_probe_link(struct oonf_timer_instance *ptr __attribute__((unused))) {
 
   l2neigh = NULL;
 
-  avl_for_each_element(nhdp_interface_get_tree(), ninterf, _node) {
-    interf = nhdp_interface_get_coreif(ninterf);
+  avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
+    if_listener = nhdp_interface_get_if_listener(nhdp_if);
 
-    l2net = oonf_layer2_net_get(interf->data.name);
+    l2net = oonf_layer2_net_get(if_listener->data->name);
     if (!l2net) {
       continue;
     }
 
     if(!_check_if_type(l2net)) {
       OONF_DEBUG(LOG_PROBING, "Drop interface %s (not wireless)",
-          interf->data.name);
+          if_listener->data->name);
       continue;
     }
 
     OONF_DEBUG(LOG_PROBING, "Start looking for probe candidate in interface '%s'",
-        interf->data.name);
+        if_listener->data->name);
 
-    list_for_each_element(&ninterf->_links, lnk, _if_node) {
+    list_for_each_element(&nhdp_if->_links, lnk, _if_node) {
       if (lnk->status != NHDP_LINK_SYMMETRIC) {
         /* only probe symmetric neighbors */
         continue;
index d178609..7dac94d 100644 (file)
@@ -48,8 +48,8 @@
 #include "core/oonf_logging.h"
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_rfc5444.h"
+#include "subsystems/os_interface.h"
 #include "nhdp/nhdp_hysteresis.h"
 #include "nhdp/nhdp_interfaces.h"
 #include "nhdp/nhdp_domain.h"
@@ -169,9 +169,9 @@ static struct cfg_schema_section _domain_section = {
 static const char *_dependencies[] = {
   OONF_CLOCK_SUBSYSTEM,
   OONF_CLASS_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_RFC5444_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
 };
 static struct oonf_subsystem nhdp_subsystem = {
   .name = OONF_NHDP_SUBSYSTEM,
index a3bf5bf..a20e566 100644 (file)
@@ -929,7 +929,7 @@ _recalculate_neighbor_metric(
 
   if (neighdata->best_link != NULL) {
     neighdata->best_link_ifindex =
-        nhdp_interface_get_coreif(neighdata->best_link->local_if)->data.index;
+        nhdp_interface_get_if_listener(neighdata->best_link->local_if)->data->index;
   }
 
   if (memcmp(&oldmetric, &neighdata->metric, sizeof(oldmetric)) != 0) {
index 32d8d7a..6c6391a 100644 (file)
@@ -54,9 +54,9 @@
 #include "core/oonf_cfg.h"
 #include "core/oonf_logging.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_rfc5444.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 
 #include "nhdp/nhdp.h"
 #include "nhdp/nhdp_db.h"
@@ -226,8 +226,8 @@ nhdp_interface_add(const char *name) {
     }
 
     /* allocate core interface */
-    interf->core_if_listener.name = interf->rfc5444_if.interface->name;
-    oonf_interface_add_listener(&interf->core_if_listener);
+    interf->os_if_listener.name = interf->rfc5444_if.interface->name;
+    os_interface_add(&interf->os_if_listener);
 
     /* initialize timers */
     interf->_hello_timer.class = &_interface_hello_timer;
@@ -310,7 +310,7 @@ nhdp_interface_remove(struct nhdp_interface *interf) {
   avl_remove(&_interface_tree, &interf->_node);
 
   /* now clean up the rest */
-  oonf_interface_remove_listener(&interf->core_if_listener);
+  os_interface_remove(&interf->os_if_listener);
   oonf_rfc5444_remove_interface(interf->rfc5444_if.interface, &interf->rfc5444_if);
   oonf_class_free(&_interface_info, interf);
 }
@@ -489,11 +489,11 @@ _cb_interface_event(struct oonf_rfc5444_interface_listener *ifl,
     bool changed __attribute__((unused))) {
   struct nhdp_interface *interf;
   struct nhdp_interface_addr *addr, *addr_it;
-  struct os_interface *oonf_interf;
+  struct os_interface_listener *if_listener;
   struct nhdp_link *nhdp_link, *nhdp_link_it;
+  struct os_interface_ip *os_ip;
   bool has_active_addr;
   bool ipv4, ipv6;
-  size_t i;
 #ifdef OONF_LOG_DEBUG_INFO
   struct netaddr_str nbuf;
 #endif
@@ -509,33 +509,29 @@ _cb_interface_event(struct oonf_rfc5444_interface_listener *ifl,
 
   has_active_addr = false;
 
-  oonf_interf = oonf_rfc5444_get_core_interface(ifl->interface);
-  if (oonf_interf != NULL && oonf_interf->data.up) {
+  if_listener = oonf_rfc5444_get_core_if_listener(ifl->interface);
+  if (if_listener != NULL && if_listener->data && if_listener->data->up) {
     ipv4 = oonf_rfc5444_is_target_active(interf->rfc5444_if.interface->multicast4);
     ipv6 = oonf_rfc5444_is_target_active(interf->rfc5444_if.interface->multicast6);
 
-    if (oonf_interf->data.up) {
-      /* get all socket addresses that are matching the filter */
-      for (i = 0; i<oonf_interf->data.addrcount; i++) {
-        struct netaddr *ifaddr = &oonf_interf->data.addresses[i];
-
-        OONF_DEBUG(LOG_NHDP, "Found interface address %s",
-            netaddr_to_string(&nbuf, ifaddr));
-
-        if (netaddr_get_address_family(ifaddr) == AF_INET && !ipv4) {
-          /* ignore IPv4 addresses if ipv4 socket is not up*/
-          continue;
-        }
-        if (netaddr_get_address_family(ifaddr) == AF_INET6 && !ipv6) {
-          /* ignore IPv6 addresses if ipv6 socket is not up*/
-          continue;
-        }
-
-        /* check if IP address fits to ACL */
-        if (netaddr_acl_check_accept(&interf->ifaddr_filter, ifaddr)) {
-          _addr_add(interf, ifaddr);
-          has_active_addr = true;
-        }
+    /* get all socket addresses that are matching the filter */
+    avl_for_each_element(&if_listener->data->addresses, os_ip, _node) {
+      OONF_DEBUG(LOG_NHDP, "Found interface address %s",
+          netaddr_to_string(&nbuf, &os_ip->address));
+
+      if (netaddr_get_address_family(&os_ip->address) == AF_INET && !ipv4) {
+        /* ignore IPv4 addresses if ipv4 socket is not up*/
+        continue;
+      }
+      if (netaddr_get_address_family(&os_ip->address) == AF_INET6 && !ipv6) {
+        /* ignore IPv6 addresses if ipv6 socket is not up*/
+        continue;
+      }
+
+      /* check if IP address fits to ACL */
+      if (netaddr_acl_check_accept(&interf->ifaddr_filter, &os_ip->address)) {
+        _addr_add(interf, &os_ip->address);
+        has_active_addr = true;
       }
     }
   }
index fece5e3..faf90ec 100644 (file)
@@ -55,9 +55,9 @@ struct nhdp_interface_domaindata;
 #include "common/list.h"
 #include "common/netaddr.h"
 #include "common/netaddr_acl.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_rfc5444.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 
 #include "nhdp/nhdp_db.h"
 
@@ -76,7 +76,7 @@ struct nhdp_interface {
   struct oonf_rfc5444_interface_listener rfc5444_if;
 
   /*! make sure interface data is available */
-  struct oonf_interface_listener core_if_listener;
+  struct os_interface_listener os_if_listener;
 
   /*! interval between two hellos sent through this interface */
   uint64_t refresh_interval;
@@ -309,9 +309,9 @@ nhdp_interface_link_get_by_originator(
  * @param nhdp_if pointer to nhdp interface
  * @return pointer to corresponding os_interface
  */
-static INLINE struct os_interface *
-nhdp_interface_get_coreif(struct nhdp_interface *nhdp_if) {
-  return nhdp_if->core_if_listener.interface;
+static INLINE struct os_interface_listener *
+nhdp_interface_get_if_listener(struct nhdp_interface *nhdp_if) {
+  return &nhdp_if->os_if_listener;
 }
 
 #endif /* NHDP_INTERFACES_H_ */
index 595c800..2e6b04c 100644 (file)
@@ -155,7 +155,7 @@ nhdp_writer_cleanup(void) {
 void
 nhdp_writer_send_hello(struct nhdp_interface *ninterf) {
   enum rfc5444_result result;
-  struct os_interface *interf;
+  struct os_interface_listener *interf;
   struct netaddr_str buf;
 
   if (_cleanedup) {
@@ -163,8 +163,8 @@ nhdp_writer_send_hello(struct nhdp_interface *ninterf) {
     return;
   }
 
-  interf = nhdp_interface_get_coreif(ninterf);
-  if (interf->data.loopback) {
+  interf = nhdp_interface_get_if_listener(ninterf);
+  if (interf->data->if_type == OS_IFTYPE_LOOPBACK) {
     /* no NHDP on loopback interface */
     return;
   }
@@ -258,7 +258,7 @@ _cb_addMessageTLVs(struct rfc5444_writer *writer) {
   uint8_t vtime_encoded, itime_encoded;
   struct oonf_rfc5444_target *target;
   const struct netaddr *v4_originator;
-  struct os_interface_data *ifdata;
+  struct os_interface *os_if;
   uint8_t willingness[NHDP_MAXIMUM_DOMAINS];
   size_t willingness_size;
   uint8_t mprtypes[NHDP_MAXIMUM_DOMAINS];
@@ -308,14 +308,11 @@ _cb_addMessageTLVs(struct rfc5444_writer *writer) {
   }
 
   /* add mac address of local interface */
-  ifdata = oonf_interface_get_data(target->interface->name, NULL);
-  if (ifdata == NULL) {
-    return;
-  }
+  os_if = nhdp_interface_get_if_listener(_nhdp_if)->data;
 
   if (_add_mac_tlv) {
     rfc5444_writer_add_messagetlv(writer, NHDP_MSGTLV_MAC, 0,
-        netaddr_get_binptr(&ifdata->mac), netaddr_get_binlength(&ifdata->mac));
+        netaddr_get_binptr(&os_if->mac), netaddr_get_binlength(&os_if->mac));
   }
 }
 
index b93b2c0..f36a050 100644 (file)
@@ -532,10 +532,10 @@ _cb_nhdpinfo_help(struct oonf_telnet_data *con) {
  */
 static void
 _initialize_interface_values(struct nhdp_interface *nhdp_if) {
-  struct os_interface *core_if;
+  struct os_interface_listener *if_listener;
   struct netaddr temp_addr;
 
-  core_if = nhdp_interface_get_coreif(nhdp_if);
+  if_listener = nhdp_interface_get_if_listener(nhdp_if);
 
   /* fill output buffers for template engine */
   strscpy(_value_if, nhdp_interface_get_name(nhdp_if), sizeof(_value_if));
@@ -548,7 +548,7 @@ _initialize_interface_values(struct nhdp_interface *nhdp_if) {
       &nhdp_if->rfc5444_if.interface->_socket.socket_v6.local_socket);
   netaddr_to_string(&_value_if_bindto_v6, &temp_addr);
 
-  netaddr_to_string(&_value_if_mac, &core_if->data.mac);
+  netaddr_to_string(&_value_if_mac, &if_listener->data->mac);
 
   strscpy(_value_if_flooding_v4,
       json_getbool(nhdp_if->use_ipv4_for_flooding), TEMPLATE_JSON_BOOL_LENGTH);
index a99bc81..54fc93b 100644 (file)
@@ -57,6 +57,7 @@
 #include "subsystems/oonf_rfc5444.h"
 #include "subsystems/oonf_telnet.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 
 #include "nhdp/nhdp_interfaces.h"
 
@@ -145,7 +146,7 @@ static void _parse_lan_array(struct cfg_named_section *section, bool add);
 static void _cb_generate_tc(struct oonf_timer_instance *);
 
 static void _update_originator(int af_family);
-static int _cb_if_event(struct oonf_interface_listener *);
+static int _cb_if_event(struct os_interface_listener *);
 
 static void _cb_cfg_olsrv2_changed(void);
 static void _cb_cfg_domain_changed(void);
@@ -211,9 +212,9 @@ static struct cfg_schema_section _olsrv2_section = {
 
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_RFC5444_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
   OONF_NHDP_SUBSYSTEM,
 };
 static struct oonf_subsystem _olsrv2_subsystem = {
@@ -242,8 +243,8 @@ static struct oonf_timer_instance _tc_timer = {
 };
 
 /* global interface listener */
-static struct oonf_interface_listener _if_listener = {
-  .process = _cb_if_event,
+static struct os_interface_listener _if_listener = {
+  .if_changed = _cb_if_event,
 };
 
 /* global variables */
@@ -289,7 +290,7 @@ _init(void) {
   }
 
   /* activate interface listener */
-  oonf_interface_add_listener(&_if_listener);
+  os_interface_add(&_if_listener);
 
   /* activate the rest of the olsrv2 protocol */
   olsrv2_lan_init();
@@ -320,7 +321,7 @@ _initiate_shutdown(void) {
 static void
 _cleanup(void) {
   /* remove interface listener */
-  oonf_interface_remove_listener(&_if_listener);
+  os_interface_remove(&_if_listener);
 
   /* cleanup configuration */
   netaddr_acl_remove(&_olsrv2_config.routable);
@@ -804,13 +805,13 @@ _get_addr_priority(const struct netaddr *addr) {
 static void
 _update_originator(int af_family) {
   const struct netaddr *originator;
-  struct nhdp_interface *n_interf;
-  struct os_interface *interf;
+  struct nhdp_interface *nhdp_if;
+  struct os_interface_listener *if_listener;
   struct netaddr new_originator;
+  struct os_interface_ip *ip;
   int new_priority;
   int old_priority;
   int priority;
-  size_t i;
 #ifdef OONF_LOG_DEBUG_INFO
   struct netaddr_str buf;
 #endif
@@ -825,26 +826,24 @@ _update_originator(int af_family) {
 
   netaddr_invalidate(&new_originator);
 
-  avl_for_each_element(nhdp_interface_get_tree(), n_interf, _node) {
-    interf = nhdp_interface_get_coreif(n_interf);
+  avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
+    if_listener = nhdp_interface_get_if_listener(nhdp_if);
 
     /* check if originator is still valid */
-    for (i=0; i<interf->data.addrcount; i++) {
-      struct netaddr *addr = &interf->data.addresses[i];
-
-      if (netaddr_get_address_family(addr) == af_family) {
-        priority = _get_addr_priority(addr);
+    avl_for_each_element(&if_listener->data->addresses, ip, _node) {
+      if (netaddr_get_address_family(&ip->address) == af_family) {
+        priority = _get_addr_priority(&ip->address);
         if (priority == 0) {
           /* not useful */
           continue;
         }
 
-        if (netaddr_cmp(originator, addr) == 0) {
+        if (netaddr_cmp(originator, &ip->address) == 0) {
           old_priority = priority + 1;
         }
 
         if (priority > old_priority && priority > new_priority) {
-          memcpy(&new_originator, addr, sizeof(new_originator));
+          memcpy(&new_originator, &ip->address, sizeof(new_originator));
           new_priority = priority;
         }
       }
@@ -864,7 +863,7 @@ _update_originator(int af_family) {
  * @return always 0
  */
 static int
-_cb_if_event(struct oonf_interface_listener *listener __attribute__((unused))) {
+_cb_if_event(struct os_interface_listener *if_listener __attribute__((unused))) {
   _update_originator(AF_INET);
   _update_originator(AF_INET6);
   return 0;
index 3352bba..dc96cfc 100644 (file)
@@ -50,8 +50,8 @@
 #include "common/netaddr_acl.h"
 #include "core/oonf_logging.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_timer.h"
+#include "subsystems/os_interface.h"
 
 #include "nhdp/nhdp.h"
 
index eb4127f..697c262 100644 (file)
@@ -6,7 +6,6 @@ SET(SINGLE_FILE_NAMES    class
                          clock
                          duplicate_set
                          http
-                         interface
                          layer2
                          packet_socket
                          socket
@@ -56,9 +55,11 @@ IF(LINUX)
     SET(OS_CLOCK_INCLUDE     ${OS_CLOCK_INCLUDE}
                              os_linus/os_clock_linux.h)
     
-    SET(OS_INTERFACE_SOURCE  os_linux/os_interface_linux.c)
+    SET(OS_INTERFACE_SOURCE  os_linux/os_interface_linux.c
+                             os_generic/os_interface_generic.c)
     SET(OS_INTERFACE_INCLUDE ${OS_INTERFACE_INCLUDE}
-                             os_linux/os_interface_linux.h)
+                             os_linux/os_interface_linux.h
+                             os_generic/os_interface_generic.h)
 
     SET(OS_ROUTING_SOURCE    os_generic/os_routing_generic_rt_to_string.c
                              os_generic/os_routing_generic_rtkey_avlcomp.c
diff --git a/src-plugins/subsystems/oonf_interface.c b/src-plugins/subsystems/oonf_interface.c
deleted file mode 100644 (file)
index 0333e29..0000000
+++ /dev/null
@@ -1,815 +0,0 @@
-
-/*
- * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
- * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * 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
- *   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
- *   distribution.
- * * 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
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Visit http://www.olsr.org for more information.
- *
- * If you find this software useful feel free to make a donation
- * to the project. For more information see the website or contact
- * the copyright holders.
- *
- */
-
-/**
- * @file
- */
-
-#include <netinet/in.h>
-
-#include "common/common_types.h"
-#include "common/avl.h"
-#include "common/avl_comp.h"
-#include "common/list.h"
-#include "common/netaddr.h"
-#include "common/netaddr_acl.h"
-#include "common/string.h"
-
-#include "core/oonf_cfg.h"
-#include "core/oonf_logging.h"
-#include "core/oonf_main.h"
-#include "core/oonf_subsystem.h"
-#include "subsystems/oonf_class.h"
-#include "subsystems/oonf_timer.h"
-#include "subsystems/os_interface.h"
-#include "subsystems/os_system.h"
-
-#include "subsystems/oonf_interface.h"
-
-/* Definitions */
-#define LOG_INTERFACE _oonf_interface_subsystem.logging
-
-/*! timeinterval to delay change in interface to trigger actions */
-#define OONF_INTERFACE_CHANGE_INTERVAL 100
-
-/* prototypes */
-static int _init(void);
-static void _cleanup(void);
-static void _early_cfg_init(void);
-
-static const struct netaddr *_get_fixed_prefix(
-    int af_type, struct netaddr_acl *filter);
-static const struct netaddr *_get_exact_match_bindaddress(
-    int af_type, struct netaddr_acl *filter, struct os_interface_data *ifdata);
-static const struct netaddr *_get_matching_bindaddress(
-    int af_type, struct netaddr_acl *filter, struct os_interface_data *ifdata);
-
-static struct os_interface *_interface_add(const char *, bool mesh);
-static void _interface_remove(struct os_interface *interf, bool mesh);
-static int _handle_unused_parameter(const char *);
-static void _cb_change_event(struct oonf_timer_instance *);
-static void _change_handler(struct os_interface *interf);
-static void _trigger_ifgeneric_change_timer(void);
-static void _trigger_ifspecific_change_timer(struct os_interface *);
-
-/* global tree of known interfaces */
-static struct avl_tree _oonf_interface_tree;
-
-/* subsystem definition */
-static const char *_dependencies[] = {
-  OONF_CLASS_SUBSYSTEM,
-  OONF_TIMER_SUBSYSTEM,
-  OONF_OS_SYSTEM_SUBSYSTEM,
-  OONF_OS_INTERFACE_SUBSYSTEM,
-};
-
-static struct oonf_subsystem _oonf_interface_subsystem = {
-  .name = OONF_INTERFACE_SUBSYSTEM,
-  .dependencies = _dependencies,
-  .dependencies_count = ARRAYSIZE(_dependencies),
-  .early_cfg_init = _early_cfg_init,
-  .init = _init,
-  .cleanup = _cleanup,
-};
-DECLARE_OONF_PLUGIN(_oonf_interface_subsystem);
-
-static struct list_entity _interface_listener;
-static struct oonf_timer_class _change_timer_info = {
-  .name = "Interface change",
-  .callback = _cb_change_event,
-};
-static struct oonf_timer_instance _other_if_change_timer = {
-  .class = &_change_timer_info,
-};
-static uint64_t _other_retrigger_timeout;
-
-static struct os_interface_if_listener _iflistener = {
-  .if_changed = oonf_interface_trigger_ifindex,
-};
-
-static struct oonf_class _if_class = {
-  .name = OONF_CLASS_INTERFACE,
-  .size = sizeof(struct os_interface),
-};
-
-/**
- * Initialize interface subsystem
- * @return always returns 0
- */
-static int
-_init(void) {
-  /* initialize data structures */
-  oonf_timer_add(&_change_timer_info);
-  oonf_class_add(&_if_class);
-
-  avl_init(&_oonf_interface_tree, avl_comp_strcasecmp, false);
-  list_init_head(&_interface_listener);
-
-  os_interface_listener_add(&_iflistener);
-  return 0;
-}
-
-/**
- * Cleanup interface subsystem
- */
-static void
-_cleanup(void) {
-  struct oonf_interface_listener *listener, *l_it;
-
-  list_for_each_element_safe(&_interface_listener, listener, _node, l_it) {
-    oonf_interface_remove_listener(listener);
-  }
-
-  os_interface_listener_remove(&_iflistener);
-  oonf_class_remove(&_if_class);
-  oonf_timer_remove(&_change_timer_info);
-}
-
-static
-void _early_cfg_init(void) {
-  oonf_main_set_parameter_handler(_handle_unused_parameter);
-}
-
-/**
- * Add a listener to a specific interface
- * @param listener initialized listener object
- * @return -1 if an error happened, 0 otherwise
- */
-int
-oonf_interface_add_listener(
-    struct oonf_interface_listener *listener) {
-  if (list_is_node_added(&listener->_node)) {
-    return 0;
-  }
-
-  OONF_DEBUG(LOG_INTERFACE, "Add listener for interface %s", listener->name);
-
-  if (listener->name && listener->name[0]) {
-    listener->interface = _interface_add(listener->name, listener->mesh);
-    if (listener->interface == NULL) {
-      return -1;
-    }
-  }
-
-  list_add_tail(&_interface_listener, &listener->_node);
-  return 0;
-}
-
-/**
- * Removes a listener to an interface object
- * @param listener pointer to listener object
- */
-void
-oonf_interface_remove_listener(
-    struct oonf_interface_listener *listener) {
-  if (!list_is_node_added(&listener->_node)) {
-    return;
-  }
-
-  OONF_DEBUG(LOG_INTERFACE, "Remove listener for interface %s", listener->name);
-
-  if (listener->interface) {
-    _interface_remove(listener->interface, listener->mesh);
-  }
-
-  list_remove(&listener->_node);
-}
-
-/**
- * Trigger a potential change in the interface settings. Normally
- * called by os_system code
- * @param if_index interface index
- * @param down true if interface is going down, false otherwise
- */
-void
-oonf_interface_trigger_ifindex(unsigned if_index, bool down) {
-  char if_name[IF_NAMESIZE];
-  struct os_interface *interf = NULL, *if_ptr;
-
-  if (if_indextoname(if_index, if_name) != NULL) {
-    interf = avl_find_element(&_oonf_interface_tree, if_name, interf, _node);
-  }
-
-  if (interf == NULL) {
-    avl_for_each_element(&_oonf_interface_tree, if_ptr, _node) {
-      if (if_ptr->data.index == if_index) {
-        interf = if_ptr;
-      }
-    }
-  }
-
-  if (interf == NULL) {
-    OONF_INFO(LOG_INTERFACE, "Unknown interface update: %d", if_index);
-    _trigger_ifgeneric_change_timer();
-    return;
-  }
-  if (down) {
-    interf->data.up = false;
-  }
-
-  oonf_interface_trigger(interf);
-}
-
-/**
- * Trigger the interface change handler after a short waiting period
- * to accumulate multiple change events.
- * @param interf pointer to olsr interface
- */
-void
-oonf_interface_trigger(struct os_interface *interf) {
-  /* trigger interface reload in 100 ms */
-  OONF_DEBUG(LOG_INTERFACE, "Change of interface %s was triggered", interf->data.name);
-
-  _trigger_ifspecific_change_timer(interf);
-}
-
-/**
- * Trigger the interface change handler after a short waiting period
- * to accumulate multiple change events.
- * @param listener pointer to interface change handler
- */
-void
-oonf_interface_trigger_handler(struct oonf_interface_listener *listener) {
-  /* trigger interface reload in 100 ms */
-  OONF_DEBUG(LOG_INTERFACE, "Change of interface listener was triggered");
-
-  listener->trigger_again = true;
-  if (listener->interface) {
-    listener->interface->retrigger_timeout = IF_RETRIGGER_INTERVAL;
-    oonf_timer_set(&listener->interface->_change_timer, IF_RETRIGGER_INTERVAL);
-  }
-  else {
-    _other_retrigger_timeout = IF_RETRIGGER_INTERVAL;
-    oonf_timer_set(&_other_if_change_timer, IF_RETRIGGER_INTERVAL);
-  }
-}
-
-/**
- * @param name interface name
- * @param buf optional pointer to helper buffer, if not NULL and the
- *   interface data wasn't cached, it will be read into the helper
- *   buffer directly.
- * @return pointer to olsr interface data, NULL if not found
- */
-struct os_interface_data *
-oonf_interface_get_data(const char *name, struct os_interface_data *buf) {
-  struct os_interface *interf;
-
-  interf = avl_find_element(&_oonf_interface_tree, name, interf, _node);
-  if (interf == NULL) {
-    if (buf) {
-      if (os_interface_update(buf, name)) {
-        return NULL;
-      }
-      return buf;
-    }
-    return NULL;
-  }
-
-  return &interf->data;
-}
-
-/**
- * Search for an interface by its index
- * @param ifindex index of the interface
- * @return interface data, NULL if not found
- */
-struct os_interface_data *
-oonf_interface_get_data_by_ifindex(unsigned ifindex) {
-  struct os_interface *interf;
-
-  avl_for_each_element(&_oonf_interface_tree, interf, _node) {
-    if (interf->data.index == ifindex) {
-      return &interf->data;
-    }
-  }
-  return NULL;
-}
-
-/**
- * Search for an interface by its base-index
- * @param ifindex index of the interface
- * @return first fitting interface data, NULL if not found
- */
-struct os_interface_data *
-oonf_interface_get_data_by_ifbaseindex(unsigned ifindex) {
-  struct os_interface *interf;
-
-  avl_for_each_element(&_oonf_interface_tree, interf, _node) {
-    if (interf->data.base_index == ifindex) {
-      return &interf->data;
-    }
-  }
-  return NULL;
-}
-
-/**
- * Get the prefix of an interface fitting to a destination address
- * @param destination destination address
- * @param ifdata interface data, NULL to search over all interfaces
- * @return network prefix (including full host), NULL if not found
- */
-const struct netaddr *
-oonf_interface_get_prefix_from_dst(
-    struct netaddr *destination, struct os_interface_data *ifdata) {
-  struct os_interface *interf;
-  const struct netaddr *result;
-  size_t i;
-#ifdef OONF_LOG_DEBUG_INFO
-  struct netaddr_str nbuf1, nbuf2;
-#endif
-
-  if (ifdata == NULL) {
-    avl_for_each_element(&_oonf_interface_tree, interf, _node) {
-      result = oonf_interface_get_prefix_from_dst(destination, &interf->data);
-      if (result) {
-        return result;
-      }
-    }
-    return NULL;
-  }
-
-  for (i=0; i<ifdata->prefixcount; i++) {
-    if (netaddr_is_in_subnet(&ifdata->prefixes[i], destination)) {
-      OONF_DEBUG(LOG_INTERFACE, "destination %s query matched if prefix: %s",
-          netaddr_to_string(&nbuf1, destination),
-          netaddr_to_string(&nbuf2, &ifdata->prefixes[i]));
-
-      return &ifdata->prefixes[i];
-    }
-  }
-
-  return NULL;
-}
-
-/**
- * Calculate the IP address a socket should bind to
- * @param af_type address family for result
- * @param filter filter for IP address to bind on
- * @param ifdata interface to bind to socket on, NULL if not
- *   bound to an interface.
- * @return pointer to address, NULL if no valid address was found
- */
-const struct netaddr *
-oonf_interface_get_bindaddress(int af_type,
-    struct netaddr_acl *filter, struct os_interface_data *ifdata) {
-  const struct netaddr *result;
-  size_t i;
-#ifdef OONF_LOG_DEBUG_INFO
-  struct netaddr_str nbuf;
-#endif
-
-  OONF_DEBUG(LOG_INTERFACE, "Find bindto (%s) for acl (if=%s):",
-      af_type == AF_INET ? "ipv4" : "ipv6",
-      !ifdata ? "any" : ifdata->name);
-
-  for (i=0; i<filter->accept_count; i++) {
-    OONF_DEBUG_NH(LOG_INTERFACE, "\taccept: %s", netaddr_to_string(&nbuf, &filter->accept[i]));
-  }
-  for (i=0; i<filter->reject_count; i++) {
-    OONF_DEBUG_NH(LOG_INTERFACE, "\treject: %s", netaddr_to_string(&nbuf, &filter->reject[i]));
-  }
-  OONF_DEBUG_NH(LOG_INTERFACE, "\t%s_first, %s_default",
-      filter->reject_first ? "reject" : "accept",
-      filter->accept_default ? "accept" : "reject");
-
-  result = NULL;
-  if (ifdata == NULL) {
-    OONF_DEBUG(LOG_INTERFACE, "Look for fixed prefix");
-    result = _get_fixed_prefix(af_type, filter);
-  }
-  if (!result) {
-    OONF_DEBUG(LOG_INTERFACE, "Look for exact match");
-    result = _get_exact_match_bindaddress(af_type, filter, ifdata);
-  }
-  if (!result) {
-    OONF_DEBUG(LOG_INTERFACE, "Look for prefix match");
-    result = _get_matching_bindaddress(af_type, filter, ifdata);
-  }
-  OONF_DEBUG(LOG_INTERFACE, "Bind to '%s'", netaddr_to_string(&nbuf, result));
-  return result;
-}
-
-/**
- * Get tree of OONF managed interfaces
- * @return interface tree
- */
-struct avl_tree *
-oonf_interface_get_tree(void) {
-  return &_oonf_interface_tree;
-}
-
-/**
- * Checks if the whole ACL is one maximum length address
- * (or two, one for each possible address type).
- * @param af_type requested address family
- * @param filter filter to parse
- * @return pointer to address to bind socket to, NULL if no match
- */
-static const struct netaddr *
-_get_fixed_prefix(int af_type, struct netaddr_acl *filter) {
-  const struct netaddr *first, *second;
-  if (filter->reject_count > 0) {
-    return NULL;
-  }
-
-  if (filter->accept_count == 0 || filter->accept_count > 2) {
-    return NULL;
-  }
-
-  first = &filter->accept[0];
-  if (netaddr_get_prefix_length(first) != netaddr_get_maxprefix(first)) {
-    return NULL;
-  }
-
-  if (filter->accept_count == 2) {
-    second = &filter->accept[1];
-
-    if (netaddr_get_address_family(first) ==
-        netaddr_get_address_family(second)) {
-      /* must be two different address families */
-      return NULL;
-    }
-
-    if (netaddr_get_prefix_length(second) != netaddr_get_maxprefix(second)) {
-      return NULL;
-    }
-    if (netaddr_get_address_family(second) == af_type) {
-      return second;
-    }
-  }
-
-  if (netaddr_get_address_family(first) == af_type) {
-    return first;
-  }
-  return NULL;
-}
-
-/**
- * Finds an IP on an/all interfaces that matches an exact (maximum length)
- * filter rule
- *
- * @param af_type address family type to look for
- * @param filter filter that must be matched
- * @param ifdata interface to look through, NULL for all interfaces
- * @return pointer to address to bind socket to, NULL if no match
- */
-static const struct netaddr *
-_get_exact_match_bindaddress(int af_type, struct netaddr_acl *filter,
-    struct os_interface_data *ifdata) {
-  struct os_interface *interf;
-  const struct netaddr *result;
-  size_t i,j;
-
-  /* handle the 'all interfaces' case */
-  if (ifdata == NULL) {
-    avl_for_each_element(&_oonf_interface_tree, interf, _node) {
-      if ((result = _get_exact_match_bindaddress(af_type, filter, &interf->data)) != NULL) {
-        return result;
-      }
-    }
-    return NULL;
-  }
-
-  /* run through all filters */
-  for (i=0; i<filter->accept_count; i++) {
-    /* look for maximum prefix length filters */
-    if (netaddr_get_prefix_length(&filter->accept[i]) != netaddr_get_af_maxprefix(af_type)) {
-      continue;
-    }
-
-    /* run through all interface addresses and look for match */
-    for (j=0; j<ifdata->addrcount; j++) {
-      if (netaddr_cmp(&ifdata->addresses[j], &filter->accept[i]) == 0) {
-        return &filter->accept[i];
-      }
-    }
-  }
-
-  /* no exact match found */
-  return NULL;
-}
-
-/**
- * Finds an IP on an/all interfaces that matches a filter rule
- *
- * @param af_type address family type to look for
- * @param filter filter that must be matched
- * @param ifdata interface to look through, NULL for all interfaces
- * @return pointer to address to bind socket to, NULL if no match
- */
-static const struct netaddr *
-_get_matching_bindaddress(int af_type, struct netaddr_acl *filter,
-    struct os_interface_data *ifdata) {
-  struct os_interface *interf;
-  const struct netaddr *result;
-  size_t i;
-
-  /* handle the 'all interfaces' case */
-  if (ifdata == NULL) {
-    avl_for_each_element(&_oonf_interface_tree, interf, _node) {
-      if ((result = _get_matching_bindaddress(af_type, filter, &interf->data)) != NULL) {
-        return result;
-      }
-    }
-    return NULL;
-  }
-
-  /* run through interface address list looking for filter match */
-  for (i=0; i<ifdata->addrcount; i++) {
-    if (netaddr_get_address_family(&ifdata->addresses[i]) != af_type) {
-      continue;
-    }
-
-    if (netaddr_acl_check_accept(filter, &ifdata->addresses[i])) {
-      return &ifdata->addresses[i];
-    }
-  }
-  return NULL;
-}
-
-/**
- * Add an interface to the listener system
- * @param if_index index of interface
- * @param mesh true if interface is used for mesh traffic
- * @return pointer to interface struct, NULL if an error happened
- */
-static struct os_interface *
-_interface_add(const char *name, bool mesh) {
-  struct os_interface *interf;
-
-  interf = avl_find_element(&_oonf_interface_tree, name, interf, _node);
-  if (!interf) {
-    /* allocate new interface */
-    interf = oonf_class_malloc(&_if_class);
-    if (interf == NULL) {
-      return NULL;
-    }
-
-    /* hookup */
-    strscpy(interf->data.name, name, sizeof(interf->data.name));
-    interf->_node.key = interf->data.name;
-    avl_insert(&_oonf_interface_tree, &interf->_node);
-
-    interf->data.index = if_nametoindex(name);
-
-    interf->_change_timer.class = &_change_timer_info;
-
-    /* initialize data of interface */
-    os_interface_update(&interf->data, name);
-  }
-
-  /* update reference counters */
-  interf->usage_counter++;
-  if(mesh) {
-    if (interf->mesh_counter == 0) {
-      os_interface_init_mesh(interf);
-    }
-    interf->mesh_counter++;
-  }
-
-  OONF_INFO(LOG_INTERFACE, "interface '%s' has reference count %u", name, interf->usage_counter);
-
-  /* trigger update */
-  if (interf->usage_counter == 1) {
-    /* new interface */
-    _change_handler(interf);
-  }
-  else {
-    /* existing one, delay update */
-    _trigger_ifspecific_change_timer(interf);
-  }
-
-  return interf;
-}
-
-/**
- * Remove an interface from the listener system. If multiple listeners
- * share an interface, this will only decrease the reference counter.
- * @param interf pointer to os_interface
- */
-static void
-_interface_remove(struct os_interface *interf, bool mesh) {
-  /* handle mesh interface flag */
-  if (mesh) {
-    interf->mesh_counter--;
-
-    if (interf->mesh_counter < 1) {
-      /* no mesh interface anymore, remove routing settings */
-      os_interface_cleanup_mesh(interf);
-    }
-  }
-
-  interf->usage_counter--;
-  OONF_INFO(LOG_INTERFACE, "Interface '%s' has reference count %u", interf->data.name, interf->usage_counter);
-
-  if (interf->usage_counter > 0) {
-    return;
-  }
-
-  if (interf->data.addresses) {
-    free(interf->data.addresses);
-  }
-  avl_remove(&_oonf_interface_tree, &interf->_node);
-
-  oonf_timer_stop(&interf->_change_timer);
-  oonf_class_free(&_if_class, interf);
-}
-
-static bool
-_match_ifgeneric_listener(struct oonf_interface_listener *l) {
-  return l->process && (l->name == NULL || l->name[0] == 0);
-}
-static bool
-_should_process_ifgeneric_listener(struct oonf_interface_listener *l) {
-  return _match_ifgeneric_listener(l) && l->trigger_again;
-}
-
-static bool
-_match_ifspecific_listener(struct oonf_interface_listener *l, const char *ifname) {
-  return (l->process && l->name != NULL && strcmp(l->name, ifname) == 0)
-      || _match_ifgeneric_listener(l);
-}
-
-static bool
-_should_process_ifspecific_listener(struct oonf_interface_listener *l, const char *ifname) {
-  return _match_ifspecific_listener(l, ifname) && l->trigger_again;
-}
-
-static bool
-_trigger_listener(struct oonf_interface_listener *l, struct os_interface_data *old) {
-  bool trouble = false;
-
-  if (l->process) {
-    l->old = old;
-
-    if (l->process(l)) {
-      trouble = true;
-    }
-    else {
-      l->trigger_again = false;
-    }
-    l->old = false;
-  }
-  return trouble;
-}
-
-/**
- * Callback when an interface changed
- * @param ptr timer instance that fired
- */
-static void
-_cb_change_event(struct oonf_timer_instance *ptr) {
-  struct os_interface *interf = NULL;
-
-  if (ptr != &_other_if_change_timer) {
-    interf = container_of(ptr, struct os_interface, _change_timer);
-  }
-  _change_handler(interf);
-}
-
-/**
- * Timer callback to handle potential change of data of an interface
- * @param ptr pointer to interface object
- */
-static void
-_change_handler(struct os_interface *interf) {
-  struct os_interface_data old_data, new_data;
-  struct oonf_interface_listener *listener, *l_it;
-  bool trouble = false;
-
-  OONF_DEBUG(LOG_INTERFACE, "Change of interface %s in progress",
-      interf == NULL ? "any" : interf->data.name);
-
-  if (!interf) {
-    /* call generic listeners */
-    list_for_each_element_safe(&_interface_listener, listener, _node, l_it) {
-
-      if (_should_process_ifgeneric_listener(listener)) {
-        if (_trigger_listener(listener, NULL)) {
-          trouble = true;
-        }
-      }
-    }
-
-    if (trouble) {
-      /* trigger callback again after a timeout */
-      _other_retrigger_timeout *= 2ull;
-      oonf_timer_set(&_other_if_change_timer, _other_retrigger_timeout);
-    }
-    else {
-      _other_retrigger_timeout = IF_RETRIGGER_INTERVAL;
-    }
-    return;
-  }
-
-  /* read interface data */
-  memset(&new_data, 0, sizeof(new_data));
-  if (os_interface_update(&new_data, interf->data.name)) {
-    /* an error happened, try again */
-    OONF_INFO(LOG_INTERFACE, "Could not query os network interface %s, trying again soon",
-        interf->data.name);
-    _trigger_ifspecific_change_timer(interf);
-    return;
-  }
-
-  /* copy data to interface object, but remember the old data */
-  memcpy(&old_data, &interf->data, sizeof(old_data));
-  memcpy(&interf->data, &new_data, sizeof(interf->data));
-
-  /* call listeners */
-  list_for_each_element_safe(&_interface_listener, listener, _node, l_it) {
-    if (_should_process_ifspecific_listener(listener, interf->data.name)) {
-      if (_trigger_listener(listener, &old_data)) {
-        trouble = true;
-      }
-    }
-  }
-
-  if (trouble) {
-    /* trigger callback again after a timeout */
-    interf->retrigger_timeout *= 2ull;
-    oonf_timer_set(&interf->_change_timer, interf->retrigger_timeout);
-  }
-
-  if (old_data.addresses) {
-    free (old_data.addresses);
-  }
-}
-
-/**
- * Activate the change timer of an unknown interface
- */
-static void
-_trigger_ifgeneric_change_timer(void) {
-  struct oonf_interface_listener *listener;
-
-  list_for_each_element(&_interface_listener, listener, _node) {
-    if (_match_ifgeneric_listener(listener)) {
-      listener->trigger_again = true;
-    }
-  }
-  _other_retrigger_timeout = IF_RETRIGGER_INTERVAL;
-  oonf_timer_set(&_other_if_change_timer, OONF_INTERFACE_CHANGE_INTERVAL);
-}
-
-/**
- * Activate the change timer of an interface object
- * @param interf pointer to interface object
- */
-static void
-_trigger_ifspecific_change_timer(struct os_interface *interf) {
-  struct oonf_interface_listener *listener;
-
-  list_for_each_element(&_interface_listener, listener, _node) {
-    if (_match_ifspecific_listener(listener, interf->data.name)) {
-      listener->trigger_again = true;
-    }
-  }
-  interf->retrigger_timeout = IF_RETRIGGER_INTERVAL;
-  oonf_timer_set(&interf->_change_timer, OONF_INTERFACE_CHANGE_INTERVAL);
-}
-
-static int
-_handle_unused_parameter(const char *arg) {
-  cfg_db_add_namedsection(oonf_cfg_get_rawdb(), CFG_INTERFACE_SECTION, arg);
-  return 0;
-}
diff --git a/src-plugins/subsystems/oonf_interface.h b/src-plugins/subsystems/oonf_interface.h
deleted file mode 100644 (file)
index 047d548..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-
-/*
- * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
- * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * 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
- *   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
- *   distribution.
- * * 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
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Visit http://www.olsr.org for more information.
- *
- * If you find this software useful feel free to make a donation
- * to the project. For more information see the website or contact
- * the copyright holders.
- *
- */
-
-/**
- * @file
- */
-
-#ifndef INTERFACE_H_
-#define INTERFACE_H_
-
-#include "common/common_types.h"
-#include "common/avl.h"
-#include "common/list.h"
-#include "common/netaddr.h"
-#include "common/netaddr_acl.h"
-#include "os_fd.h"
-
-#include "subsystems/oonf_timer.h"
-
-/*! subsystem identifier */
-#define OONF_INTERFACE_SUBSYSTEM "interface"
-
-/*! memory class for oonf interfaces */
-#define OONF_CLASS_INTERFACE             "oonf_interface"
-
-/*! interface configuration section name */
-#define CFG_INTERFACE_SECTION      "interface"
-
-/*! interface configuration section mode */
-#define CFG_INTERFACE_SECTION_MODE CFG_SSMODE_NAMED
-
-/*! wildcard name for interfaces */
-#define OONF_INTERFACE_WILDCARD "any"
-
-/*! interval after a failed interface change listener should be triggered again */
-#define IF_RETRIGGER_INTERVAL 1000ull
-
-/**
- * Status listener for oonf interface
- */
-struct oonf_interface_listener {
-  /*! name of interface */
-  const char *name;
-
-  /**
-   * set to true if listener is on a mesh traffic interface.
-   * keep this false if in doubt, true will trigger some interface
-   * reconfiguration to allow forwarding of user traffic
-   */
-  bool mesh;
-
-  /**
-   * callback for interface change event
-   * @param l pointer to this interface listener
-   * @return -1 if interface was not ready and
-   *   listener should be called again
-   */
-  int (*process)(struct oonf_interface_listener *l);
-
-  /*! true if process should be triggered again */
-  bool trigger_again;
-
-  /*! pointer to the interface this listener is registered to */
-  struct os_interface *interface;
-
-  /**
-   * pointer to the interface data before the change happened, will be
-   * set by the core while process() is called
-   */
-  struct os_interface_data *old;
-
-  /*! hook into list of listeners */
-  struct list_entity _node;
-};
-
-EXPORT int oonf_interface_add_listener(struct oonf_interface_listener *);
-EXPORT void oonf_interface_remove_listener(struct oonf_interface_listener *);
-
-EXPORT struct os_interface_data *oonf_interface_get_data(
-    const char *name, struct os_interface_data *buffer);
-EXPORT struct os_interface_data *oonf_interface_get_data_by_ifindex(
-    unsigned ifindex);
-EXPORT struct os_interface_data *oonf_interface_get_data_by_ifbaseindex(
-               unsigned ifindex);
-
-EXPORT void oonf_interface_trigger(struct os_interface *interf);
-EXPORT void oonf_interface_trigger_ifindex(unsigned if_index, bool down);
-EXPORT void oonf_interface_trigger_handler(struct oonf_interface_listener *listener);
-
-EXPORT const struct netaddr *oonf_interface_get_bindaddress(int af_type,
-    struct netaddr_acl *filter, struct os_interface_data *ifdata);
-EXPORT const struct netaddr *oonf_interface_get_prefix_from_dst(
-    struct netaddr *destination, struct os_interface_data *ifdata);
-
-EXPORT struct avl_tree *oonf_interface_get_tree(void);
-
-#endif /* INTERFACE_H_ */
index fff620c..6ea5739 100644 (file)
@@ -50,7 +50,7 @@
 #include "config/cfg_schema.h"
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
+#include "subsystems/os_interface.h"
 
 #include "subsystems/oonf_layer2.h"
 
@@ -67,7 +67,7 @@ static void _neigh_remove(struct oonf_layer2_neigh *l2neigh);
 /* subsystem definition */
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
 };
 
 static struct oonf_subsystem _oonf_layer2_subsystem = {
@@ -224,7 +224,7 @@ oonf_layer2_net_add(const char *ifname) {
 
   /* initialize interface listener */
   l2net->if_listener.name = l2net->name;
-  oonf_interface_add_listener(&l2net->if_listener);
+  os_interface_add(&l2net->if_listener);
 
   oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_ADDED);
 
@@ -628,7 +628,7 @@ _net_remove(struct oonf_layer2_net *l2net) {
   oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_REMOVED);
 
   /* remove interface listener */
-  oonf_interface_remove_listener(&l2net->if_listener);
+  os_interface_remove(&l2net->if_listener);
 
   /* free addr */
   avl_remove(&_oonf_layer2_net_tree, &l2net->_node);
index e2291a7..ad4f067 100644 (file)
@@ -49,7 +49,7 @@
 #include "common/avl.h"
 #include "common/common_types.h"
 #include "core/oonf_subsystem.h"
-#include "subsystems/oonf_interface.h"
+#include "subsystems/os_interface.h"
 
 /*! subsystem identifier */
 #define OONF_LAYER2_SUBSYSTEM "layer2"
@@ -201,7 +201,7 @@ struct oonf_layer2_net {
   enum oonf_layer2_network_type if_type;
 
   /*! interface listener to keep track of events and local mac address */
-  struct oonf_interface_listener if_listener;
+  struct os_interface_listener if_listener;
 
   /*! tree of remote neighbors */
   struct avl_tree neighbors;
index 2071efe..74221ba 100644 (file)
@@ -52,7 +52,7 @@
 #include "common/netaddr_acl.h"
 #include "core/oonf_logging.h"
 #include "core/oonf_subsystem.h"
-#include "subsystems/oonf_interface.h"
+#include "subsystems/os_interface.h"
 #include "subsystems/oonf_socket.h"
 #include "subsystems/os_fd.h"
 #include "subsystems/oonf_packet_socket.h"
@@ -65,24 +65,24 @@ static int _init(void);
 static void _cleanup(void);
 
 static void _packet_add(struct oonf_packet_socket *pktsocket,
-    union netaddr_socket *local, struct os_interface_data *interf);
+    union netaddr_socket *local, struct os_interface *os_if);
 static int _apply_managed(struct oonf_packet_managed *managed);
 static int _apply_managed_socketpair(int af_type,
     struct oonf_packet_managed *managed,
-    struct os_interface_data *data, bool *changed,
+    struct os_interface *os_if, bool *changed,
     struct oonf_packet_socket *sock,
     struct oonf_packet_socket *mc_sock, struct netaddr *mc_ip);
 static int _apply_managed_socket(struct oonf_packet_managed *managed,
     struct oonf_packet_socket *stream, const struct netaddr *bindto,
-    int port, uint8_t dscp, int protocol, struct os_interface_data *data);
+    int port, uint8_t dscp, int protocol, struct os_interface *os_if);
 static void _cb_packet_event_unicast(struct oonf_socket_entry *);
 static void _cb_packet_event_multicast(struct oonf_socket_entry *);
 static void _cb_packet_event(struct oonf_socket_entry *, bool mc);
-static int _cb_interface_listener(struct oonf_interface_listener *l);
+static int _cb_interface_listener(struct os_interface_listener *l);
 
 /* subsystem definition */
 static const char *_dependencies[] = {
-  OONF_INTERFACE_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
   OONF_SOCKET_SUBSYSTEM,
   OONF_OS_FD_SUBSYSTEM,
 };
@@ -128,20 +128,20 @@ _cleanup(void) {
  * Add a new packet socket handler
  * @param pktsocket pointer to an initialized packet socket struct
  * @param local pointer local IP address of packet socket
- * @param interf pointer to interface to bind socket on, NULL
+ * @param os_if pointer to interface to bind socket on, NULL
  *   if socket should not be bound to interface
  * @return -1 if an error happened, 0 otherwise
  */
 int
 oonf_packet_add(struct oonf_packet_socket *pktsocket,
-    union netaddr_socket *local, struct os_interface_data *interf) {
+    union netaddr_socket *local, struct os_interface *os_if) {
   /* Init socket */
   if (os_fd_getsocket(
-      &pktsocket->scheduler_entry.fd, local, false, 0, interf, LOG_PACKET)) {
+      &pktsocket->scheduler_entry.fd, local, false, 0, os_if, LOG_PACKET)) {
     return -1;
   }
 
-  _packet_add(pktsocket, local, interf);
+  _packet_add(pktsocket, local, os_if);
   return 0;
 }
 
@@ -156,7 +156,7 @@ oonf_packet_add(struct oonf_packet_socket *pktsocket,
  */
 int
 oonf_packet_raw_add(struct oonf_packet_socket *pktsocket, int protocol,
-    union netaddr_socket *local, struct os_interface_data *interf) {
+    union netaddr_socket *local, struct os_interface *interf) {
   /* Init socket */
   if (os_fd_getrawsocket(
       &pktsocket->scheduler_entry.fd, local, false, 0, interf, LOG_PACKET)) {
@@ -171,8 +171,8 @@ oonf_packet_raw_add(struct oonf_packet_socket *pktsocket, int protocol,
 
 static void
 _packet_add(struct oonf_packet_socket *pktsocket,
-    union netaddr_socket *local, struct os_interface_data *interf) {
-  pktsocket->interface = interf;
+    union netaddr_socket *local, struct os_interface *interf) {
+  pktsocket->os_if = interf;
   pktsocket->scheduler_entry.process = _cb_packet_event_unicast;
 
   oonf_socket_add(&pktsocket->scheduler_entry);
@@ -230,7 +230,7 @@ oonf_packet_send(struct oonf_packet_socket *pktsocket, union netaddr_socket *rem
       /* successful */
       OONF_DEBUG(LOG_PACKET, "Sent %d bytes to %s %s",
           result, netaddr_socket_to_string(&buf, remote),
-          pktsocket->interface != NULL ? pktsocket->interface->name : "");
+          pktsocket->os_if != NULL ? pktsocket->os_if->name : "");
       return 0;
     }
 
@@ -266,7 +266,7 @@ oonf_packet_add_managed(struct oonf_packet_managed *managed) {
     managed->config.input_buffer_length = sizeof(_input_buffer);
   }
 
-  managed->_if_listener.process = _cb_interface_listener;
+  managed->_if_listener.if_changed = _cb_interface_listener;
   managed->_if_listener.name = managed->_managed_config.interface;
   managed->_if_listener.mesh = managed->_managed_config.mesh;
 }
@@ -283,7 +283,7 @@ oonf_packet_remove_managed(struct oonf_packet_managed *managed, bool forced) {
   oonf_packet_remove(&managed->multicast_v4, forced);
   oonf_packet_remove(&managed->multicast_v6, forced);
 
-  oonf_interface_remove_listener(&managed->_if_listener);
+  os_interface_remove(&managed->_if_listener);
   oonf_packet_free_managed_config(&managed->_managed_config);
 }
 
@@ -308,21 +308,21 @@ oonf_packet_apply_managed(struct oonf_packet_managed *managed,
   /* handle change in interface listener */
   if (if_changed) {
     /* interface changed, remove old listener if necessary */
-    oonf_interface_remove_listener(&managed->_if_listener);
+    os_interface_remove(&managed->_if_listener);
 
     /* create new interface listener */
     managed->_if_listener.mesh = managed->_managed_config.mesh;
-    oonf_interface_add_listener(&managed->_if_listener);
+    os_interface_add(&managed->_if_listener);
   }
 
   OONF_DEBUG(LOG_PACKET, "Apply changes for managed socket (if %s) with port %d/%d",
-      config->interface == NULL || config->interface[0] == 0 ? "any" : config->interface,
+      config->interface[0] == 0 ? "any" : config->interface,
       config->port, config->multicast_port);
 
   result = _apply_managed(managed);
   if (result) {
     /* did not work, trigger interface handler to try later again */
-    oonf_interface_trigger_handler(&managed->_if_listener);
+    os_interface_trigger_handler(&managed->_if_listener);
   }
   return result;
 }
@@ -443,22 +443,22 @@ oonf_packet_free_managed_config(struct oonf_packet_managed_config *config) {
  */
 static int
 _apply_managed(struct oonf_packet_managed *managed) {
-  struct os_interface_data *data = NULL;
+  struct os_interface *os_if = NULL;
   bool changed = false;
   int result = 0;
 
   /* get interface */
-  if (managed->_if_listener.interface) {
-    data = &managed->_if_listener.interface->data;
+  if (managed->_if_listener.name) {
+    os_if = managed->_if_listener.data;
   }
 
-  if (_apply_managed_socketpair(AF_INET, managed, data, &changed,
+  if (_apply_managed_socketpair(AF_INET, managed, os_if, &changed,
       &managed->socket_v4, &managed->multicast_v4,
       &managed->_managed_config.multicast_v4)) {
     result = -1;
   }
 
-  if (_apply_managed_socketpair(AF_INET6, managed, data, &changed,
+  if (_apply_managed_socketpair(AF_INET6, managed, os_if, &changed,
       &managed->socket_v6, &managed->multicast_v6,
       &managed->_managed_config.multicast_v6)) {
     result = -1;
@@ -482,7 +482,7 @@ _apply_managed(struct oonf_packet_managed *managed) {
  */
 static int
 _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed,
-    struct os_interface_data *data, bool *changed,
+    struct os_interface *os_if, bool *changed,
     struct oonf_packet_socket *sock,
     struct oonf_packet_socket *mc_sock, struct netaddr *mc_ip) {
   struct netaddr_acl *bind_ip_acl;
@@ -500,16 +500,21 @@ _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed,
   }
 
   /* Get address the unicast socket should bind on */
-  if (data != NULL && !data->up) {
+  if (os_if != NULL && !os_if->up) {
     bind_ip = NULL;
   }
-  else if (data != NULL && netaddr_get_address_family(data->linklocal_v6_ptr) == af_type &&
-      netaddr_acl_check_accept(bind_ip_acl, data->linklocal_v6_ptr)) {
+  else if (os_if != NULL && netaddr_get_address_family(os_if->if_linklocal_v6) == af_type &&
+      netaddr_acl_check_accept(bind_ip_acl, os_if->if_linklocal_v6)) {
+
+    bind_ip = os_if->if_linklocal_v6;
+  }
+  else if (os_if != NULL && netaddr_get_address_family(os_if->if_linklocal_v4) == af_type &&
+      netaddr_acl_check_accept(bind_ip_acl, os_if->if_linklocal_v4)) {
 
-    bind_ip = data->linklocal_v6_ptr;
+    bind_ip = os_if->if_linklocal_v4;
   }
   else {
-    bind_ip = oonf_interface_get_bindaddress(af_type, bind_ip_acl, data);
+    bind_ip = os_interface_get_bindaddress(af_type, bind_ip_acl, os_if);
   }
   if (!bind_ip) {
     oonf_packet_remove(sock, false);
@@ -518,7 +523,7 @@ _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed,
   }
 
   /* handle loopback interface */
-  if (data != NULL && data->loopback
+  if (os_if != NULL && os_if->if_type == OS_IFTYPE_LOOPBACK
       && netaddr_get_address_family(mc_ip) != AF_UNSPEC) {
     memcpy(mc_ip, bind_ip, sizeof(*mc_ip));
   }
@@ -533,14 +538,14 @@ _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed,
       managed, sock, bind_ip, managed->_managed_config.port,
       managed->_managed_config.dscp,
       managed->_managed_config.rawip ? managed->_managed_config.protocol : 0,
-      data);
+      os_if);
   if (sockstate == 0) {
     /* settings really changed */
     *changed = true;
 
-    if (real_multicast && data != NULL && data->up) {
+    if (real_multicast && os_if != NULL && os_if->up) {
       os_fd_join_mcast_send(&sock->scheduler_entry.fd,
-          mc_ip, data, managed->_managed_config.loop_multicast, LOG_PACKET);
+          mc_ip, os_if, managed->_managed_config.loop_multicast, LOG_PACKET);
     }
   }
   else if (sockstate < 0) {
@@ -554,7 +559,7 @@ _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed,
     sockstate = _apply_managed_socket(
         managed, mc_sock, mc_ip, mc_port, managed->_managed_config.dscp,
         managed->_managed_config.rawip ? managed->_managed_config.protocol : 0,
-        data);
+        os_if);
     if (sockstate == 0) {
       /* settings really changed */
       *changed = true;
@@ -563,7 +568,7 @@ _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed,
 
       /* join multicast group */
       os_fd_join_mcast_recv(&mc_sock->scheduler_entry.fd,
-          mc_ip, data, LOG_PACKET);
+          mc_ip, os_if, LOG_PACKET);
     }
     else if (sockstate < 0) {
       /* error */
@@ -579,7 +584,7 @@ _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed,
      * oonf_packet_send_managed_multicast()
      */
     netaddr_socket_init(&mc_sock->local_socket, mc_ip, mc_port,
-        data == NULL ? 0 : data->index);
+        os_if == NULL ? 0 : os_if->index);
   }
   return result;
 }
@@ -601,7 +606,7 @@ static int
 _apply_managed_socket(struct oonf_packet_managed *managed,
     struct oonf_packet_socket *packet,
     const struct netaddr *bindto, int port, uint8_t dscp,
-    int protocol, struct os_interface_data *data) {
+    int protocol, struct os_interface *data) {
   union netaddr_socket sock;
   struct netaddr_str buf;
 
@@ -614,7 +619,7 @@ _apply_managed_socket(struct oonf_packet_managed *managed,
   }
 
   if (list_is_node_added(&packet->node)) {
-    if (data == packet->interface
+    if (data == packet->os_if
         && memcmp(&sock, &packet->local_socket, sizeof(sock)) == 0
         && protocol == packet->protocol) {
       /* nothing changed */
@@ -662,7 +667,7 @@ _apply_managed_socket(struct oonf_packet_managed *managed,
     oonf_packet_remove(packet, true);
     return -1;
   }
-  packet->interface = data;
+  packet->os_if = data;
 
   OONF_DEBUG(LOG_PACKET, "Opened new socket and bound it to %s (if %s)",
       netaddr_to_string(&buf, bindto),
@@ -718,8 +723,8 @@ _cb_packet_event(struct oonf_socket_entry *entry,
   pktsocket = container_of(entry, typeof(*pktsocket), scheduler_entry);
 
 #ifdef OONF_LOG_DEBUG_INFO
-  if (pktsocket->interface) {
-    interf = pktsocket->interface->name;
+  if (pktsocket->os_if) {
+    interf = pktsocket->os_if->name;
   }
 #endif
 
@@ -734,7 +739,7 @@ _cb_packet_event(struct oonf_socket_entry *entry,
 
     result = os_fd_recvfrom(&entry->fd,
         buf, pktsocket->config.input_buffer_length-1, &sock,
-        pktsocket->interface);
+        pktsocket->os_if);
     if (result > 0 && pktsocket->config.receive_data != NULL) {
       /* handle raw socket */
       if (pktsocket->protocol) {
@@ -806,7 +811,7 @@ _cb_packet_event(struct oonf_socket_entry *entry,
  * @return -1 if an error happened, 0 otherwise
  */
 static int
-_cb_interface_listener(struct oonf_interface_listener *l) {
+_cb_interface_listener(struct os_interface_listener *l) {
   struct oonf_packet_managed *managed;
   int result;
 
index 7ba696b..ae30b7c 100644 (file)
@@ -51,7 +51,7 @@
 #include "common/autobuf.h"
 #include "common/netaddr.h"
 #include "common/netaddr_acl.h"
-#include "subsystems/oonf_interface.h"
+#include "subsystems/os_interface.h"
 #include "subsystems/oonf_socket.h"
 
 #ifndef _WIN32
@@ -110,7 +110,7 @@ struct oonf_packet_socket {
   struct autobuf out;
 
   /*! interface data the socket is bound to */
-  struct os_interface_data *interface;
+  struct os_interface *os_if;
 
   /*! configuration of packet socket */
   struct oonf_packet_config config;
@@ -195,13 +195,13 @@ struct oonf_packet_managed {
   struct oonf_packet_managed_config _managed_config;
 
   /*! interface listener to detect changes */
-  struct oonf_interface_listener _if_listener;
+  struct os_interface_listener _if_listener;
 };
 
 EXPORT int oonf_packet_add(struct oonf_packet_socket *,
-    union netaddr_socket *local, struct os_interface_data *);
+    union netaddr_socket *local, struct os_interface *);
 EXPORT int oonf_packet_raw_add(struct oonf_packet_socket *, int protocol,
-    union netaddr_socket *local, struct os_interface_data *interf);
+    union netaddr_socket *local, struct os_interface *os_if);
 EXPORT void oonf_packet_remove(struct oonf_packet_socket *, bool);
 
 EXPORT int oonf_packet_send(struct oonf_packet_socket *,
index 5d383f9..83655ab 100644 (file)
@@ -872,7 +872,7 @@ oonf_rfc5444_target_get_local_socket(struct oonf_rfc5444_target *target) {
 }
 
 /**
- * @param interface oonf rfc5444 interface
+ * @param rfc5444_if oonf rfc5444 interface
  * @param af_type address family type
  * @return local socket corresponding to address family
  */
@@ -1073,12 +1073,14 @@ static void
 _cb_send_multicast_packet(struct rfc5444_writer *writer __attribute__((unused)),
     struct rfc5444_writer_target *target, void *ptr, size_t len) {
   struct oonf_rfc5444_target *t;
+  struct os_interface_listener *if_listener;
   union netaddr_socket sock;
 
   t = container_of(target, struct oonf_rfc5444_target, rfc5444_target);
 
+  if_listener = oonf_rfc5444_get_core_if_listener(t->interface);
   netaddr_socket_init(&sock, &t->dst, t->interface->protocol->port,
-      t->interface->_socket._if_listener.interface->data.index);
+      if_listener->data->index);
 
   _print_packet_to_buffer(LOG_RFC5444_W, &sock, t->interface, ptr, len,
       "Outgoing RFC5444 packet to",
@@ -1104,11 +1106,13 @@ _cb_send_unicast_packet(struct rfc5444_writer *writer __attribute__((unused)),
     struct rfc5444_writer_target *target, void *ptr, size_t len) {
   struct oonf_rfc5444_target *t;
   union netaddr_socket sock;
+  struct os_interface_listener *interf;
 
   t = container_of(target, struct oonf_rfc5444_target, rfc5444_target);
 
+  interf = oonf_rfc5444_get_core_if_listener(t->interface);
   netaddr_socket_init(&sock, &t->dst, t->interface->protocol->port,
-      t->interface->_socket._if_listener.interface->data.index);
+      interf->data->index);
 
   _print_packet_to_buffer(LOG_RFC5444_W, &sock, t->interface, ptr, len,
       "Outgoing RFC5444 packet to",
index 89b0ae7..25787e9 100644 (file)
@@ -92,7 +92,7 @@ enum {
 #define RFC5444_PROTOCOL "rfc5444_default"
 
 /*! Interface name for unicast targets */
-#define RFC5444_UNICAST_INTERFACE OONF_INTERFACE_WILDCARD
+#define RFC5444_UNICAST_INTERFACE OS_INTERFACE_ANY
 
 /*! memory class for rfc5444 protocol */
 #define RFC5444_CLASS_PROTOCOL  "RFC5444 protocol"
@@ -321,9 +321,9 @@ oonf_rfc5444_get_target_from_rfc5444_target(struct rfc5444_writer_target *target
  * @param interf pointer to rfc5444 interface
  * @return pointer to olsr interface
  */
-static INLINE struct os_interface *
-oonf_rfc5444_get_core_interface(struct oonf_rfc5444_interface *interf) {
-  return interf->_socket._if_listener.interface;
+static INLINE struct os_interface_listener *
+oonf_rfc5444_get_core_if_listener(struct oonf_rfc5444_interface *interf) {
+  return &interf->_socket._if_listener;
 }
 
 /**
index e79994a..c91e9ae 100644 (file)
@@ -53,9 +53,9 @@
 #include "core/oonf_logging.h"
 #include "core/oonf_subsystem.h"
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
 #include "subsystems/oonf_timer.h"
 #include "subsystems/oonf_stream_socket.h"
+#include "subsystems/os_interface.h"
 #include "subsystems/os_system.h"
 #include "subsystems/os_fd.h"
 
@@ -69,7 +69,7 @@ static void _cleanup(void);
 static void _stream_close(struct oonf_stream_session *session);
 int _apply_managed(struct oonf_stream_managed *managed);
 static int _apply_managed_socket(int af_type, struct oonf_stream_managed *managed,
-    struct oonf_stream_socket *stream, struct os_interface_data *data);
+    struct oonf_stream_socket *stream, struct os_interface *os_if);
 static void _cb_parse_request(struct oonf_socket_entry *);
 static struct oonf_stream_session *_create_session(
     struct oonf_stream_socket *stream_socket, struct os_fd *sock,
@@ -78,7 +78,7 @@ static struct oonf_stream_session *_create_session(
 static void _cb_parse_connection(struct oonf_socket_entry *entry);
 
 static void _cb_timeout_handler(struct oonf_timer_instance *);
-static int _cb_interface_listener(struct oonf_interface_listener *l);
+static int _cb_interface_listener(struct os_interface_listener *listener);
 
 /* list of olsr stream sockets */
 static struct list_entity _stream_head;
@@ -97,11 +97,11 @@ static struct oonf_timer_class _connection_timeout = {
 /* subsystem definition */
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_SOCKET_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
-  OONF_OS_SYSTEM_SUBSYSTEM,
   OONF_OS_FD_SUBSYSTEM,
+  OONF_OS_INTERFACE_SUBSYSTEM,
+  OONF_OS_SYSTEM_SUBSYSTEM,
 };
 
 static struct oonf_subsystem _oonf_stream_socket_subsystem = {
@@ -342,7 +342,7 @@ oonf_stream_add_managed(struct oonf_stream_managed *managed) {
     managed->config.session_timeout = 120000;
   }
 
-  managed->_if_listener.process = _cb_interface_listener;
+  managed->_if_listener.if_changed = _cb_interface_listener;
   managed->_if_listener.name = managed->_managed_config.interface;
 }
 
@@ -371,10 +371,10 @@ oonf_stream_apply_managed(struct oonf_stream_managed *managed,
   /* handle change in interface listener */
   if (if_changed) {
     /* interface changed, remove old listener if necessary */
-    oonf_interface_remove_listener(&managed->_if_listener);
+    os_interface_remove(&managed->_if_listener);
 
     /* create new interface listener */
-    oonf_interface_add_listener(&managed->_if_listener);
+    os_interface_add(&managed->_if_listener);
   }
 
   OONF_DEBUG(LOG_STREAM, "Apply changes for managed socket (if %s) with port %d",
@@ -384,7 +384,7 @@ oonf_stream_apply_managed(struct oonf_stream_managed *managed,
   result = _apply_managed(managed);
   if (result) {
     /* did not work, trigger interface handler to try later again */
-    oonf_interface_trigger_handler(&managed->_if_listener);
+    os_interface_trigger_handler(&managed->_if_listener);
   }
   return result;
 }
@@ -397,11 +397,11 @@ oonf_stream_apply_managed(struct oonf_stream_managed *managed,
  */
 void
 oonf_stream_remove_managed(struct oonf_stream_managed *managed, bool force) {
-  oonf_interface_remove_listener(&managed->_if_listener);
+  os_interface_remove(&managed->_if_listener);
 
   oonf_stream_remove(&managed->socket_v4, force);
   oonf_stream_remove(&managed->socket_v6, force);
-  oonf_interface_remove_listener(&managed->_if_listener);
+  os_interface_remove(&managed->_if_listener);
   oonf_stream_free_managed_config(&managed->_managed_config);
 }
 
@@ -479,19 +479,19 @@ _stream_close(struct oonf_stream_session *session) {
  */
 int
 _apply_managed(struct oonf_stream_managed *managed) {
-  struct os_interface_data *data = NULL;
+  struct os_interface *bind_socket_to_if = NULL;
 
   /* get interface */
-  if (managed->_if_listener.interface) {
-    data = &managed->_if_listener.interface->data;
+  if (managed->_if_listener.data->if_type != OS_IFTYPE_ANY) {
+    bind_socket_to_if = managed->_if_listener.data;
   }
 
-  if (_apply_managed_socket(AF_INET, managed, &managed->socket_v4, data)) {
+  if (_apply_managed_socket(AF_INET, managed, &managed->socket_v4, bind_socket_to_if)) {
     return -1;
   }
 
   if (os_system_is_ipv6_supported()) {
-    if (_apply_managed_socket(AF_INET6, managed, &managed->socket_v6, data)) {
+    if (_apply_managed_socket(AF_INET6, managed, &managed->socket_v6, bind_socket_to_if)) {
       return -1;
     }
   }
@@ -507,7 +507,7 @@ _apply_managed(struct oonf_stream_managed *managed) {
  */
 static int
 _apply_managed_socket(int af_type, struct oonf_stream_managed *managed,
-    struct oonf_stream_socket *stream, struct os_interface_data *data) {
+    struct oonf_stream_socket *stream, struct os_interface *data) {
   struct netaddr_acl *bind_ip_acl;
   const struct netaddr *bind_ip;
   union netaddr_socket sock;
@@ -519,13 +519,14 @@ _apply_managed_socket(int af_type, struct oonf_stream_managed *managed,
   if (data != NULL && !data->up) {
     bind_ip = NULL;
   }
-  else if (data != NULL && netaddr_get_address_family(data->linklocal_v6_ptr) == af_type &&
-      netaddr_acl_check_accept(bind_ip_acl, data->linklocal_v6_ptr)) {
+  else if (data != NULL
+      && netaddr_get_address_family(data->if_linklocal_v6) == af_type
+      && netaddr_acl_check_accept(bind_ip_acl, data->if_linklocal_v6)) {
 
-    bind_ip = data->linklocal_v6_ptr;
+    bind_ip = data->if_linklocal_v6;
   }
   else {
-    bind_ip = oonf_interface_get_bindaddress(af_type, bind_ip_acl, data);
+    bind_ip = os_interface_get_bindaddress(af_type, bind_ip_acl, data);
   }
   if (!bind_ip) {
     oonf_stream_remove(stream, true);
@@ -868,17 +869,18 @@ _cb_parse_connection(struct oonf_socket_entry *entry) {
  * @return -1 if an error happened, 0 otherwise
  */
 static int
-_cb_interface_listener(struct oonf_interface_listener *l) {
+_cb_interface_listener(struct os_interface_listener *interf) {
   struct oonf_stream_managed *managed;
   int result;
 
   /* calculate managed socket for this event */
-  managed = container_of(l, struct oonf_stream_managed, _if_listener);
+  managed = container_of(interf, struct oonf_stream_managed, _if_listener);
 
   result = _apply_managed(managed);
 
   OONF_DEBUG(LOG_STREAM,
-      "Result from interface triggered socket reconfiguration: %d", result);
+      "Result from interface %s triggered socket reconfiguration: %d",
+      interf->name, result);
 
   return result;
 }
index eda93f2..bd634b7 100644 (file)
@@ -53,7 +53,7 @@
 #include "common/netaddr_acl.h"
 
 #include "subsystems/oonf_class.h"
-#include "subsystems/oonf_interface.h"
+#include "subsystems/os_interface.h"
 #include "subsystems/oonf_socket.h"
 #include "subsystems/oonf_timer.h"
 
@@ -293,7 +293,7 @@ struct oonf_stream_managed {
   struct oonf_stream_managed_config _managed_config;
 
   /*! listener to interface the socket is bound to */
-  struct oonf_interface_listener _if_listener;
+  struct os_interface_listener _if_listener;
 };
 
 EXPORT int oonf_stream_add(struct oonf_stream_socket *,
index a6b1e5f..61304ce 100644 (file)
@@ -202,12 +202,6 @@ oonf_timer_start_ext(struct oonf_timer_instance *timer, uint64_t first, uint64_t
   OONF_DEBUG(LOG_TIMER, "TIMER: start timer '%s' firing in %s (%"PRIu64")\n",
       timer->class->name,
       oonf_clock_toClockString(&timebuf1, first), timer->_clock);
-
-  /* fix 'next event' pointers if necessary */
-  if (_scheduling_now) {
-    /* will be fixed at the end of the timer scheduling loop */
-    return;
-  }
 }
 
 /**
index e9be02d..c3b6c0a 100644 (file)
@@ -71,7 +71,7 @@ static INLINE int os_fd_get_fd(struct os_fd *);
 static INLINE int os_fd_invalidate(struct os_fd *);
 static INLINE bool os_fd_is_initialized(struct os_fd *);
 
-static INLINE int os_fd_bindto_interface(struct os_fd *, struct os_interface_data *data);
+static INLINE int os_fd_bindto_interface(struct os_fd *, struct os_interface *);
 static INLINE int os_fd_close(struct os_fd *);
 static INLINE int os_fd_listen(struct os_fd *, int n);
 
@@ -97,22 +97,22 @@ static INLINE int os_fd_get_socket_error(struct os_fd *, int *value);
 static INLINE ssize_t os_fd_sendto(struct os_fd *, const void *buf, size_t length,
     const union netaddr_socket *dst, bool dont_route);
 static INLINE ssize_t os_fd_recvfrom(struct os_fd *, void *buf, size_t length,
-    union netaddr_socket *source, const struct os_interface_data *interf);
+    union netaddr_socket *source, const struct os_interface *);
 static INLINE const char *os_fd_get_loopback_name(void);
 static INLINE ssize_t os_fd_sendfile(struct os_fd *, struct os_fd *,
     size_t offset, size_t count);
 
 static INLINE int os_fd_getsocket(struct os_fd *, const union netaddr_socket *bindto, bool tcp,
-    size_t recvbuf, const struct os_interface_data *, enum oonf_log_source log_src);
+    size_t recvbuf, const struct os_interface *, enum oonf_log_source log_src);
 static INLINE int os_fd_getrawsocket(struct os_fd *, const union netaddr_socket *bindto, int protocol,
-    size_t recvbuf, const struct os_interface_data *, enum oonf_log_source log_src);
+    size_t recvbuf, const struct os_interface *, enum oonf_log_source log_src);
 static INLINE int os_fd_configsocket(struct os_fd *, const union netaddr_socket *bindto,
-    size_t recvbuf, bool rawip, const struct os_interface_data *, enum oonf_log_source log_src);
+    size_t recvbuf, bool rawip, const struct os_interface *, enum oonf_log_source log_src);
 static INLINE int os_fd_set_nonblocking(struct os_fd *);
 static INLINE int os_fd_join_mcast_recv(struct os_fd *, const struct netaddr *multicast,
-    const struct os_interface_data *oif, enum oonf_log_source log_src);
+    const struct os_interface *, enum oonf_log_source log_src);
 static INLINE int os_fd_join_mcast_send(struct os_fd *, const struct netaddr *multicast,
-    const struct os_interface_data *oif, bool loop, enum oonf_log_source log_src);
+    const struct os_interface *, bool loop, enum oonf_log_source log_src);
 static INLINE int os_fd_set_dscp(struct os_fd *, int dscp, bool ipv6);
 static INLINE uint8_t *os_fd_skip_rawsocket_prefix(uint8_t *ptr, ssize_t *len, int af_type);
 
index 5154b19..cb32088 100644 (file)
@@ -50,7 +50,7 @@
 #include "common/netaddr.h"
 #include "common/string.h"
 #include "core/oonf_logging.h"
-#include "subsystems/os_interface_data.h"
+#include "subsystems/os_interface.h"
 
 #include "subsystems/os_fd.h"
 #include "subsystems/os_generic/os_fd_generic_configsocket.h"
@@ -61,7 +61,7 @@
  * @param bind_to ip/port to bind the socket to
  * @param recvbuf size of input buffer for socket
  * @param rawip true if socket is a raw ip socket, false otherwise
- * @param interf pointer to interface to bind socket on,
+ * @param os_if pointer to interface to bind socket on,
  *   NULL if socket should not be bound to an interface
  * @param log_src logging source for error messages
  * @return -1 if an error happened, 0 otherwise
@@ -69,7 +69,7 @@
 int
 os_fd_generic_configsocket(struct os_fd *sock,
     const union netaddr_socket *bind_to, size_t recvbuf,
-    bool rawip, const struct os_interface_data *interf, enum oonf_log_source log_src) {
+    bool rawip, const struct os_interface *os_if, enum oonf_log_source log_src) {
   union netaddr_socket bindto;
   struct netaddr_str buf;
   socklen_t addrlen;
@@ -96,10 +96,10 @@ os_fd_generic_configsocket(struct os_fd *sock,
 
 #if defined(SO_BINDTODEVICE)
   /* this is binding the socket, not a multicast address */
-  if (interf != NULL && setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
-      interf->name, strlen(interf->name) + 1) < 0) {
+  if (os_if != NULL && setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
+      os_if->name, strlen(os_if->name) + 1) < 0) {
     OONF_WARN(log_src, "Cannot bind socket to interface %s: %s (%d)\n",
-        interf->name, strerror(errno), errno);
+        os_if->name, strerror(errno), errno);
     return -1;
   }
 #endif
@@ -115,7 +115,7 @@ os_fd_generic_configsocket(struct os_fd *sock,
 #endif
 
 #if defined(IP_RECVIF)
-  if (interf != NULL
+  if (os_if != NULL
       && setsockopt(sock, IPPROTO_IP, IP_RECVIF, &yes, sizeof(yes)) < 0) {
     OONF_WARN(log_src, "Cannot apply IP_RECVIF for %s: %s (%d)\n",
         netaddr_socket_to_string(&buf, &bindto), strerror(errno), errno);
@@ -143,8 +143,8 @@ os_fd_generic_configsocket(struct os_fd *sock,
 #endif
 
   /* add ipv6 interface scope if necessary */
-  if (interf != NULL && netaddr_socket_get_addressfamily(&bindto) == AF_INET6) {
-    bindto.v6.sin6_scope_id = interf->index;
+  if (os_if != NULL && netaddr_socket_get_addressfamily(&bindto) == AF_INET6) {
+    bindto.v6.sin6_scope_id = os_if->index;
   }
 
   /* bind the socket to the port number */
index e6a73da..2012e83 100644 (file)
 
 #include "common/common_types.h"
 #include "core/oonf_logging.h"
-#include "subsystems/os_interface_data.h"
+#include "subsystems/os_interface.h"
 #include "subsystems/os_fd.h"
 
 EXPORT int os_fd_generic_configsocket(struct os_fd *sock,
     const union netaddr_socket *bind_to, size_t recvbuf,
-    bool rawip, const struct os_interface_data *interf, enum oonf_log_source log_src);
+    bool rawip, const struct os_interface *os_if, enum oonf_log_source log_src);
 
 #endif /* _OS_FD_GENERIC_CONFIGSOCKET_H_ */
index 8f762fa..2114fcf 100644 (file)
 #include "common/netaddr.h"
 #include "core/oonf_logging.h"
 
-#include "subsystems/os_interface_data.h"
+#include "subsystems/os_interface.h"
 #include "subsystems/os_fd.h"
 #include "subsystems/os_generic/os_fd_generic_getrawsocket.h"
 
 /**
  * Creates a new raw socket and configures it
+ * @param sock empty socket instance
  * @param bind_to address to bind the socket to
  * @param protocol IP protocol number
  * @param recvbuf size of input buffer for socket
- * @param interf pointer to interface to bind socket on,
+ * @param os_if pointer to interface to bind socket on,
  *   NULL if socket should not be bound to an interface
  * @param log_src logging source for error messages
- * @return socket filedescriptor, -1 if an error happened
+ * @return -1 if an error happened, 0 otherwise
  */
 int
 os_fd_generic_getrawsocket(struct os_fd *sock,
     const union netaddr_socket *bind_to,
-    int protocol, size_t recvbuf, const struct os_interface_data *interf,
+    int protocol, size_t recvbuf, const struct os_interface *os_if,
     enum oonf_log_source log_src __attribute__((unused))) {
 
   static const int zero = 0;
@@ -88,7 +89,7 @@ os_fd_generic_getrawsocket(struct os_fd *sock,
     }
   }
 
-  if (os_fd_configsocket(sock, bind_to, recvbuf, true, interf, log_src)) {
+  if (os_fd_configsocket(sock, bind_to, recvbuf, true, os_if, log_src)) {
     os_fd_close(sock);
     return -1;
   }
index c3cad0e..ffc1708 100644 (file)
@@ -13,7 +13,7 @@
 
 EXPORT int os_fd_generic_getrawsocket(struct os_fd *sock,
     const union netaddr_socket *bind_to,
-    int protocol, size_t recvbuf, const struct os_interface_data *interf,
+    int protocol, size_t recvbuf, const struct os_interface *os_if,
     enum oonf_log_source log_src);
 
 #endif /* _OS_FD_GENERIC_GETRAWSOCKET_H_ */
index d39ee08..4c5ce96 100644 (file)
 
 /**
  * Creates a new socket and configures it
+ * @param sock empty socket instance
  * @param bind_to address to bind the socket to
  * @param tcp true for a TCP socket, false for UDP
  * @param recvbuf size of input buffer for socket
- * @param interf pointer to interface to bind socket on,
+ * @param os_if pointer to interface to bind socket on,
  *   NULL if socket should not be bound to an interface
  * @param log_src logging source for error messages
- * @return 0 if socket was created, -1 if an error happened
+ * @return -1 if an error happened, 0 otherwise
  */
 int
 os_fd_generic_getsocket(struct os_fd *sock,
     const union netaddr_socket *bind_to,
-    bool tcp, size_t recvbuf, const struct os_interface_data *interf,
+    bool tcp, size_t recvbuf, const struct os_interface *os_if,
     enum oonf_log_source log_src __attribute__((unused))) {
   int s;
   s = socket(bind_to->std.sa_family, tcp ? SOCK_STREAM : SOCK_DGRAM, 0);
@@ -80,7 +81,7 @@ os_fd_generic_getsocket(struct os_fd *sock,
     return -1;
   }
 
-  if (os_fd_configsocket(sock, bind_to, recvbuf, false, interf, log_src)) {
+  if (os_fd_configsocket(sock, bind_to, recvbuf, false, os_if, log_src)) {
     os_fd_close(sock);
     return -1;
   }
index 48007f0..979be51 100644 (file)
@@ -13,7 +13,7 @@
 
 EXPORT int os_fd_generic_getsocket(struct os_fd *sock,
     const union netaddr_socket *bind_to,
-    bool tcp, size_t recvbuf, const struct os_interface_data *interf,
+    bool tcp, size_t recvbuf, const struct os_interface *os_if,
     enum oonf_log_source log_src);
 
 #endif /* _OS_FD_GENERIC_GETSOCKET_H_ */
index 833f687..58d7c0c 100644 (file)
  * Join a socket into a multicast group
  * @param sock filedescriptor of socket
  * @param multicast multicast-group to join
- * @param oif pointer to outgoing interface data for multicast
+ * @param os_if pointer to outgoing interface data for multicast
  * @param log_src logging source for error messages
  * @return -1 if an error happened, 0 otherwise
  */
 int
 os_fd_generic_join_mcast_recv(struct os_fd *sock,
     const struct netaddr *multicast,
-    const struct os_interface_data *oif,
+    const struct os_interface *os_if,
     enum oonf_log_source log_src __attribute__((unused))) {
   struct netaddr_str buf1, buf2;
   struct ip_mreq   v4_mreq;
   struct ipv6_mreq v6_mreq;
   const char *ifname = "*";
 
-  if (oif) {
-    ifname = oif->name;
+  if (os_if) {
+    ifname = os_if->name;
   }
 
   if (netaddr_get_address_family(multicast) == AF_INET) {
     const struct netaddr *src;
 
-    src = oif == NULL ? &NETADDR_IPV4_ANY : oif->if_v4;
+    src = os_if == NULL ? &NETADDR_IPV4_ANY : os_if->if_v4;
 
     OONF_DEBUG(log_src,
         "Socket on interface %s joining receiving multicast %s (src %s)\n",
@@ -101,7 +101,7 @@ os_fd_generic_join_mcast_recv(struct os_fd *sock,
   else {
     int if_index;
 
-    if_index = oif == NULL ? 0 : oif->index;
+    if_index = os_if == NULL ? 0 : os_if->index;
 
     OONF_DEBUG(log_src,
         "Socket on interface %s joining receiving multicast %s (if %d)\n",
@@ -126,7 +126,7 @@ os_fd_generic_join_mcast_recv(struct os_fd *sock,
  * Join a socket into a multicast group
  * @param sock filedescriptor of socket
  * @param multicast multicast ip/port to join
- * @param oif pointer to outgoing interface data for multicast
+ * @param os_if pointer to outgoing interface data for multicast
  * @param loop true if multicast loop should be activated, false otherwise
  * @param log_src logging source for error messages
  * @return -1 if an error happened, 0 otherwise
@@ -134,7 +134,7 @@ os_fd_generic_join_mcast_recv(struct os_fd *sock,
 int
 os_fd_generic_join_mcast_send(struct os_fd *sock,
     const struct netaddr *multicast,
-    const struct os_interface_data *oif, bool loop,
+    const struct os_interface *os_if, bool loop,
     enum oonf_log_source log_src __attribute__((unused))) {
   struct netaddr_str buf1, buf2;
   unsigned i;
@@ -142,15 +142,15 @@ os_fd_generic_join_mcast_send(struct os_fd *sock,
   if (netaddr_get_address_family(multicast) == AF_INET) {
     OONF_DEBUG(log_src,
         "Socket on interface %s joining sending multicast %s (src %s)\n",
-        oif->name,
+        os_if->name,
         netaddr_to_string(&buf2, multicast),
-        netaddr_to_string(&buf1, oif->if_v4));
+        netaddr_to_string(&buf1, os_if->if_v4));
 
-    if (setsockopt(sock->fd, IPPROTO_IP, IP_MULTICAST_IF, netaddr_get_binptr(oif->if_v4), 4) < 0) {
+    if (setsockopt(sock->fd, IPPROTO_IP, IP_MULTICAST_IF, netaddr_get_binptr(os_if->if_v4), 4) < 0) {
       OONF_WARN(log_src, "Cannot set multicast %s on interface %s (src %s): %s (%d)\n",
           netaddr_to_string(&buf2, multicast),
-          oif->name,
-          netaddr_to_string(&buf1, oif->if_v4),
+          os_if->name,
+          netaddr_to_string(&buf1, os_if->if_v4),
           strerror(errno), errno);
       return -1;
     }
@@ -165,16 +165,16 @@ os_fd_generic_join_mcast_send(struct os_fd *sock,
   else {
     OONF_DEBUG(log_src,
         "Socket on interface %s (%d) joining sending multicast %s (src %s)\n",
-        oif->name, oif->index,
+        os_if->name, os_if->index,
         netaddr_to_string(&buf2, multicast),
-        netaddr_to_string(&buf1, oif->linklocal_v6_ptr));
+        netaddr_to_string(&buf1, os_if->if_linklocal_v6));
 
     if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
-        &oif->index, sizeof(oif->index)) < 0) {
+        &os_if->index, sizeof(os_if->index)) < 0) {
       OONF_WARN(log_src, "Cannot set multicast %s on interface %s (src %s): %s (%d)\n",
           netaddr_to_string(&buf2, multicast),
-          oif->name,
-          netaddr_to_string(&buf1, oif->linklocal_v6_ptr),
+          os_if->name,
+          netaddr_to_string(&buf1, os_if->if_linklocal_v6),
           strerror(errno), errno);
       return -1;
     }
index ce29f5f..bf12513 100644 (file)
 
 EXPORT int os_fd_generic_join_mcast_recv(struct os_fd *sock,
     const struct netaddr *multicast,
-    const struct os_interface_data *oif,
+    const struct os_interface *os_if,
     enum oonf_log_source log_src);
 
 EXPORT int os_fd_generic_join_mcast_send(struct os_fd *sock,
     const struct netaddr *multicast,
-    const struct os_interface_data *oif, bool loop,
+    const struct os_interface *os_if, bool loop,
     enum oonf_log_source log_src);
 
 #endif /* _OS_FD_GENERIC_JOIN_MCAST_H_ */
diff --git a/src-plugins/subsystems/os_generic/os_interface_generic.c b/src-plugins/subsystems/os_generic/os_interface_generic.c
new file mode 100644 (file)
index 0000000..b4c309d
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * os_interface_generic_get_bindaddress.c
+ *
+ *  Created on: 07.03.2016
+ *      Author: rogge
+ */
+
+#include "common/common_types.h"
+#include "common/avl.h"
+#include "subsystems/os_interface.h"
+
+static const struct netaddr *_get_fixed_prefix(
+    int af_type, struct netaddr_acl *filter);
+static const struct netaddr *_get_exact_match_bindaddress(
+    int af_type, struct netaddr_acl *filter,
+    struct os_interface *os_if);
+static const struct netaddr *_get_matching_bindaddress(
+    int af_type, struct netaddr_acl *filter,
+    struct os_interface *os_if);
+
+/**
+ * Calculate the IP address a socket should bind to
+ * @param af_type address family for result
+ * @param filter filter for IP address to bind on
+ * @param os_if interface to bind to socket on, NULL if not
+ *   bound to an interface.
+ * @return pointer to address, NULL if no valid address was found
+ */
+const struct netaddr *
+os_interface_generic_get_bindaddress(int af_type,
+    struct netaddr_acl *filter, struct os_interface *os_if) {
+  const struct netaddr *result;
+
+  result = NULL;
+  if (os_if == NULL) {
+    result = _get_fixed_prefix(af_type, filter);
+  }
+  if (!result) {
+    result = _get_exact_match_bindaddress(af_type, filter, os_if);
+  }
+  if (!result) {
+    result = _get_matching_bindaddress(af_type, filter, os_if);
+  }
+  return result;
+}
+
+/**
+ * Search for an interface by its base-index
+ * @param ifindex index of the interface
+ * @return first fitting interface data, NULL if not found
+ */
+struct os_interface *
+os_interface_generic_get_data_by_ifbaseindex(unsigned ifindex) {
+  struct os_interface *os_if;
+
+  avl_for_each_element(os_interface_get_tree(), os_if, _node) {
+    if (os_if->base_index == ifindex) {
+      return os_if;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * Search for an interface by its index
+ * @param ifindex index of the interface
+ * @return interface data, NULL if not found
+ */
+struct os_interface *
+os_interface_generic_get_data_by_ifindex(unsigned ifindex) {
+  struct os_interface *os_if;
+
+  avl_for_each_element(os_interface_get_tree(), os_if, _node) {
+    if (os_if->index == ifindex) {
+      return os_if;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * Get the prefix of an interface fitting to a destination address
+ * @param destination destination address
+ * @param os_if interface data, NULL to search over all interfaces
+ * @return network prefix (including full host), NULL if not found
+ */
+const struct netaddr *
+os_interface_generic_get_prefix_from_dst(
+    struct netaddr *destination, struct os_interface *os_if) {
+  struct os_interface_ip *ip;
+  const struct netaddr *result;
+
+  if (os_if == NULL) {
+    avl_for_each_element(os_interface_get_tree(), os_if, _node) {
+      result = os_interface_get_prefix_from_dst(destination, os_if);
+      if (result) {
+        return result;
+      }
+    }
+    return NULL;
+  }
+
+  avl_for_each_element(&os_if->addresses, ip, _node) {
+    if (netaddr_is_in_subnet(&ip->prefix, destination)) {
+      return &ip->prefix;
+    }
+  }
+
+  return NULL;
+}
+
+/**
+ * Checks if the whole ACL is one maximum length address
+ * (or two, one for each possible address type).
+ * @param af_type requested address family
+ * @param filter filter to parse
+ * @return pointer to address to bind socket to, NULL if no match
+ */
+static const struct netaddr *
+_get_fixed_prefix(int af_type, struct netaddr_acl *filter) {
+  const struct netaddr *first, *second;
+  if (filter->reject_count > 0) {
+    return NULL;
+  }
+
+  if (filter->accept_count == 0 || filter->accept_count > 2) {
+    return NULL;
+  }
+
+  first = &filter->accept[0];
+  if (netaddr_get_prefix_length(first) != netaddr_get_maxprefix(first)) {
+    return NULL;
+  }
+
+  if (filter->accept_count == 2) {
+    second = &filter->accept[1];
+
+    if (netaddr_get_address_family(first) ==
+        netaddr_get_address_family(second)) {
+      /* must be two different address families */
+      return NULL;
+    }
+
+    if (netaddr_get_prefix_length(second) != netaddr_get_maxprefix(second)) {
+      return NULL;
+    }
+    if (netaddr_get_address_family(second) == af_type) {
+      return second;
+    }
+  }
+
+  if (netaddr_get_address_family(first) == af_type) {
+    return first;
+  }
+  return NULL;
+}
+
+/**
+ * Finds an IP on an/all interfaces that matches an exact (maximum length)
+ * filter rule
+ *
+ * @param af_type address family type to look for
+ * @param filter filter that must be matched
+ * @param os_if interface to look through, NULL for all interfaces
+ * @return pointer to address to bind socket to, NULL if no match
+ */
+static const struct netaddr *
+_get_exact_match_bindaddress(int af_type, struct netaddr_acl *filter,
+    struct os_interface *os_if) {
+  struct os_interface_ip *ip;
+  const struct netaddr *result;
+  size_t i;
+
+  /* handle the 'all interfaces' case */
+  if (os_if == NULL) {
+    avl_for_each_element(os_interface_get_tree(), os_if, _node) {
+      if ((result = _get_exact_match_bindaddress(af_type, filter, os_if)) != NULL) {
+        return result;
+      }
+    }
+    return NULL;
+  }
+
+  /* run through all filters */
+  for (i=0; i<filter->accept_count; i++) {
+    /* look for maximum prefix length filters */
+    if (netaddr_get_prefix_length(&filter->accept[i]) != netaddr_get_af_maxprefix(af_type)) {
+      continue;
+    }
+
+    /* run through all interface addresses and look for match */
+    avl_for_each_element(&os_if->addresses, ip, _node) {
+      if (netaddr_cmp(&ip->address, &filter->accept[i]) == 0) {
+        return &filter->accept[i];
+      }
+    }
+  }
+
+  /* no exact match found */
+  return NULL;
+}
+
+/**
+ * Finds an IP on an/all interfaces that matches a filter rule
+ *
+ * @param af_type address family type to look for
+ * @param filter filter that must be matched
+ * @param os_if interface to look through, NULL for all interfaces
+ * @return pointer to address to bind socket to, NULL if no match
+ */
+static const struct netaddr *
+_get_matching_bindaddress(int af_type, struct netaddr_acl *filter,
+    struct os_interface *os_if) {
+  struct os_interface_ip *ip;
+  const struct netaddr *result;
+
+  /* handle the 'all interfaces' case */
+  if (os_if == NULL) {
+    avl_for_each_element(os_interface_get_tree(), os_if, _node) {
+      if ((result = _get_matching_bindaddress(af_type, filter, os_if)) != NULL) {
+        return result;
+      }
+    }
+    return NULL;
+  }
+
+  /* run through interface address list looking for filter match */
+  avl_for_each_element(&os_if->addresses, ip, _node) {
+    if (netaddr_get_address_family(&ip->address) != af_type) {
+      continue;
+    }
+
+    if (netaddr_acl_check_accept(filter, &ip->address)) {
+      return &ip->address;
+    }
+  }
+  return NULL;
+}
diff --git a/src-plugins/subsystems/os_generic/os_interface_generic.h b/src-plugins/subsystems/os_generic/os_interface_generic.h
new file mode 100644 (file)
index 0000000..c1d4697
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * os_interface_generic_get_bindaddress.h
+ *
+ *  Created on: 07.03.2016
+ *      Author: rogge
+ */
+
+#ifndef OS_INTERFACE_GENERIC_H_
+#define OS_INTERFACE_GENERIC_H_
+
+#include "common/common_types.h"
+#include "common/netaddr_acl.h"
+#include "subsystems/os_interface.h"
+
+EXPORT const struct netaddr *os_interface_generic_get_bindaddress(
+    int af_type, struct netaddr_acl *filter,
+    struct os_interface *os_if);
+EXPORT struct os_interface *
+    os_interface_generic_get_data_by_ifbaseindex(unsigned ifindex);
+EXPORT struct os_interface *
+    os_interface_generic_get_data_by_ifindex(unsigned ifindex);
+EXPORT const struct netaddr *os_interface_generic_get_prefix_from_dst(
+    struct netaddr *destination, struct os_interface *os_if);
+
+#endif /* OS_INTERFACE_GENERIC_H_ */
index 69f6588..dbb864c 100644 (file)
@@ -62,7 +62,7 @@ static const char *_route_types[] = {
 /**
  * Print OS route to string buffer
  * @param buf pointer to string buffer
- * @param route pointer to route
+ * @param route_parameter pointer to route
  * @return pointer to string buffer, NULL if an error happened
  */
 const char *
index cfe8217..c9295b6 100644 (file)
 #include "common/list.h"
 #include "core/oonf_logging.h"
 #include "subsystems/oonf_timer.h"
-#include "subsystems/os_interface_data.h"
+#include "subsystems/os_interface.h"
 
 /*! subsystem identifier */
 #define OONF_OS_INTERFACE_SUBSYSTEM "os_interface"
 
-/**
- * operation system listener for interface events
- */
-struct os_interface_if_listener {
-  /**
-   * Callback triggered when the interface changesd
-   * @param if_index interface index
-   * @param up true if interface is up
-   */
-  void (*if_changed)(unsigned if_index, bool up);
+/*! interface configuration section name */
+#define CFG_INTERFACE_SECTION      "interface"
 
-  /*! hook to global list of listeners */
-  struct list_entity _node;
-};
-
-struct os_interface;
-struct os_interface_address;
+/*! interface configuration section mode */
+#define CFG_INTERFACE_SECTION_MODE CFG_SSMODE_NAMED
 
 /* include os-specific headers */
 #if defined(__linux__)
-#include "subsystems/os_linux/os_interface_linux.h"
-#elif defined (BSD)
-#include "subsystems/os_bsd/os_interface_bsd.h"
-#elif defined (_WIN32)
-#include "subsystems/os_win32/os_interface_win32.h"
+#include "subsystems/os_linux/os_interface_linux_internal.h"
 #else
 #error "Unknown operation system"
 #endif
@@ -90,9 +74,9 @@ struct os_interface_address;
 /**
  * Handler for changing an interface address
  */
-struct os_interface_address {
-  /*! used for delivering feedback about netlink commands */
-  struct os_interface_address_internal _internal;
+struct os_interface_ip_change {
+  /*! operation system specific data */
+  struct os_interface_address_change_internal _internal;
 
   /*! interface address */
   struct netaddr address;
@@ -111,27 +95,72 @@ struct os_interface_address {
    * @param addr this interface address object
    * @param error error code, 0 if everything is fine
    */
-  void (*cb_finished)(struct os_interface_address *addr, int error);
+  void (*cb_finished)(struct os_interface_ip_change *addr, int error);
+};
+
+enum os_interface_type {
+  OS_IFTYPE_NORMAL,
+  OS_IFTYPE_LOOPBACK,
+  OS_IFTYPE_ANY,
 };
 
 /**
  * Representation of an operation system interface
  */
 struct os_interface {
-  /*! data of interface */
-  struct os_interface_data data;
+  /*! operation system specific data */
+  struct os_interface_internal _internal;
+
+  /*! interface name */
+  char name[IF_NAMESIZE];
+
+  /*! interface index */
+  unsigned index;
+
+  /**
+   * interface index of base interface (for vlan),
+   * same for normal interface
+   */
+  unsigned base_index;
+
+  /*! mac address of interface */
+  struct netaddr mac;
+
+  /**
+   * point to one (mesh scope) IPv4 address of the interface
+   * (or to NETADDR_UNSPEC if none available)
+   */
+  const struct netaddr *if_v4;
 
   /**
-   * usage counter to allow multiple instances to add the same
-   * interface
+   * point to one (mesh scope) IPv4 address of the interface
+   * (or to NETADDR_UNSPEC if none available)
    */
-  uint32_t usage_counter;
+  const struct netaddr *if_v6;
 
   /**
-   * usage counter to keep track of the number of users on
-   * this interface who want to send mesh traffic
+   * point to one (linklocal scope) IPv4 address of the interface
+   * (or to NETADDR_UNSPEC if none available)
    */
-  uint32_t mesh_counter;
+  const struct netaddr *if_linklocal_v4;
+
+  /**
+   * point to one (linklocal scope) IPv6 address of the interface
+   * (or to NETADDR_UNSPEC if none available)
+   */
+  const struct netaddr *if_linklocal_v6;
+
+  /*! true if the interface exists and is up */
+  bool up;
+
+  /*! type of interface */
+  enum os_interface_type if_type;
+
+  /*! tree of all addresses/prefixes of this interface */
+  struct avl_tree addresses;
+
+  /*! listeners to be informed when an interface changes */
+  struct list_entity _listeners;
 
   /**
    * When an interface change handler triggers a 'interface not ready'
@@ -140,13 +169,6 @@ struct os_interface {
    */
   uint64_t retrigger_timeout;
 
-  /**
-   * used to store internal state of interfaces before
-   * configuring them for manet data forwarding.
-   * Only used by os_specific code.
-   */
-  uint32_t _original_state;
-
   /*! hook interfaces into global tree */
   struct avl_node _node;
 
@@ -154,18 +176,75 @@ struct os_interface {
   struct oonf_timer_instance _change_timer;
 };
 
+/**
+ * Representation of an IP address/prefix of a network interface of
+ * the operation system
+ */
+struct os_interface_ip {
+  struct avl_node _node;
+
+  struct netaddr prefixed_addr;
+  struct netaddr address;
+  struct netaddr prefix;
+
+  struct os_interface *interf;
+};
+
+/**
+ * operation system listener for interface events
+ */
+struct os_interface_listener {
+  /*! name of the interface this listener is interested in */
+  const char *name;
+
+  /*! true if this interface needs to be a mesh interface */
+  bool mesh;
+
+  /**
+   * Callback triggered when the interface changed
+   * @param listener pointer to this listener
+   * @return -1 if an error happened, and the listener should be
+   *   triggered again later, 0 if everything was fine
+   */
+  int (*if_changed)(struct os_interface_listener *);
+
+  /*! pointer to interface data */
+  struct os_interface *data;
+
+  /*! true if this listener still needs to process a change */
+  bool _dirty;
+
+  /*! hook to global list of listeners */
+  struct list_entity _node;
+};
+
+/* include os-specific headers */
+#if defined(__linux__)
+#include "subsystems/os_linux/os_interface_linux.h"
+#else
+#error "Unknown operation system"
+#endif
+
 /* prototypes for all os_system functions */
-static INLINE void os_interface_listener_add(struct os_interface_if_listener *);
-static INLINE void os_interface_listener_remove(struct os_interface_if_listener *);
-static INLINE int os_interface_state_set(const char *dev, bool up);
-static INLINE int os_interface_address_set(struct os_interface_address *addr);
-static INLINE void os_interface_address_interrupt(struct os_interface_address *addr);
-static INLINE int os_interface_mac_set_by_name(const char *, struct netaddr *mac);
-
-static INLINE int os_interface_update(struct os_interface_data *, const char *);
-static INLINE int os_interface_init_mesh(struct os_interface *);
-static INLINE void os_interface_cleanup_mesh(struct os_interface *);
-
-static INLINE int os_interface_mac_set(struct os_interface_data *ifdata, struct netaddr *mac);
+static INLINE struct os_interface *os_interface_add(struct os_interface_listener *);
+static INLINE void os_interface_remove(struct os_interface_listener *);
+static INLINE struct avl_tree *os_interface_get_tree(void);
+
+static INLINE void os_interface_trigger_handler(struct os_interface_listener *);
+
+static INLINE int os_interface_state_set(struct os_interface *, bool up);
+static INLINE int os_interface_mac_set(struct os_interface *interf, struct netaddr *mac);
+
+static INLINE int os_interface_address_set(struct os_interface_ip_change *addr);
+static INLINE void os_interface_address_interrupt(struct os_interface_ip_change *addr);
+
+static INLINE struct os_interface *os_interface_get_data_by_ifindex(
+    unsigned ifindex);
+static INLINE  struct os_interface *os_interface_get_data_by_ifbaseindex(
+    unsigned ifindex);
+static INLINE  const struct netaddr *os_interface_get_bindaddress(int af_type,
+    struct netaddr_acl *filter, struct os_interface *ifdata);
+static INLINE  const struct netaddr *os_interface_get_prefix_from_dst(
+    struct netaddr *destination, struct os_interface *ifdata);
 
 #endif /* OS_INTERFACE_H_ */
index 29c269a..ed29862 100644 (file)
@@ -93,11 +93,9 @@ _cleanup(void) {
 }
 
 /**
- *
- * @param sel
- * @param event
- * @param maxdelay
- * @return
+ * wait for a network event on multiple sockets
+ * @param sel socket selector set
+ * @return number of events that happened, 0 if a timeout happened
  */
 int
 os_fd_linux_event_wait(struct os_fd_select *sel) {
@@ -125,6 +123,12 @@ os_fd_linux_event_wait(struct os_fd_select *sel) {
   return sel->_event_count;
 }
 
+/**
+ * Move the wanted events of a socket into a selector set
+ * @param sel socket selector set
+ * @param sock os socket
+ * @return -1 if an error happened, 0 otherwise
+ */
 int
 os_fd_linux_event_socket_modify(struct os_fd_select *sel,
     struct os_fd *sock) {
@@ -139,6 +143,7 @@ os_fd_linux_event_socket_modify(struct os_fd_select *sel,
       sock->fd, sock->wanted_events);
   return epoll_ctl(sel->_epoll_fd, EPOLL_CTL_MOD, sock->fd, &event);
 }
+
 /**
  * Raw IP sockets sometimes deliver the whole IP header instead of just
  * the content. This function skips the IP header and modifies the length
index 0d4ce73..b967995 100644 (file)
@@ -115,15 +115,15 @@ os_fd_event_wait(struct os_fd_select *sel) {
  * @param bindto bind socket to this address/port
  * @param tcp true if TCP socket, false if UDP socket
  * @param recvbuf size of receiver buffer
- * @param ifdata bind socket to this interface,
+ * @param os_if bind socket to this interface,
  *   NULL to not bind socket to interface
  * @param log_src logging source for error messages
  * @return -1 if an error happened, 0 otherwise
  */
 static INLINE int
 os_fd_getsocket(struct os_fd *sock, const union netaddr_socket *bindto, bool tcp,
-    size_t recvbuf, const struct os_interface_data *ifdata, enum oonf_log_source log_src) {
-  return os_fd_generic_getsocket(sock, bindto, tcp, recvbuf, ifdata, log_src);
+    size_t recvbuf, const struct os_interface *os_if, enum oonf_log_source log_src) {
+  return os_fd_generic_getsocket(sock, bindto, tcp, recvbuf, os_if, log_src);
 }
 
 /**
@@ -132,15 +132,15 @@ os_fd_getsocket(struct os_fd *sock, const union netaddr_socket *bindto, bool tcp
  * @param bindto bind socket to this address/port
  * @param protocol bind socket to this protocol
  * @param recvbuf size of receiver buffer
- * @param ifdata bind socket to this interface,
+ * @param os_if bind socket to this interface,
  *   NULL to not bind socket to interface
  * @param log_src logging source for error messages
  * @return -1 if an error happened, 0 otherwise
  */
 static INLINE int
 os_fd_getrawsocket(struct os_fd *sock, const union netaddr_socket *bindto, int protocol,
-    size_t recvbuf, const struct os_interface_data *ifdata, enum oonf_log_source log_src) {
-  return os_fd_generic_getrawsocket(sock, bindto, protocol, recvbuf, ifdata, log_src);
+    size_t recvbuf, const struct os_interface *os_if, enum oonf_log_source log_src) {
+  return os_fd_generic_getrawsocket(sock, bindto, protocol, recvbuf, os_if, log_src);
 }
 
 /**
@@ -149,15 +149,15 @@ os_fd_getrawsocket(struct os_fd *sock, const union netaddr_socket *bindto, int p
  * @param bindto bind socket to this address/port
  * @param recvbuf size of receiver buffer
  * @param rawip true if this is a raw ip socket, false otherwise
- * @param ifdata bind socket to this interface,
+ * @param os_if bind socket to this interface,
  *   NULL to not bind socket to interface
  * @param log_src logging source for error messages
  * @return -1 if an error happened, 0 otherwise
  */
 static INLINE int
 os_fd_configsocket(struct os_fd *sock, const union netaddr_socket *bindto,
-    size_t recvbuf, bool rawip, const struct os_interface_data *ifdata, enum oonf_log_source log_src) {
-  return os_fd_generic_configsocket(sock, bindto, recvbuf, rawip, ifdata, log_src);
+    size_t recvbuf, bool rawip, const struct os_interface *os_if, enum oonf_log_source log_src) {
+  return os_fd_generic_configsocket(sock, bindto, recvbuf, rawip, os_if, log_src);
 }
 
 /**
@@ -174,22 +174,22 @@ os_fd_set_nonblocking(struct os_fd *sock) {
  * Redirect to generic mcast receiver join call
  * @param sock socket representation
  * @param multicast multicast group to join
- * @param oif outgoing interface for multicast,
+ * @param os_if outgoing interface for multicast,
  *   NULL if not interface specific
  * @param log_src logging source for error messages
  * @return -1 if an error happened, 0 otherwise
  */
 static INLINE int
 os_fd_join_mcast_recv(struct os_fd *sock, const struct netaddr *multicast,
-    const struct os_interface_data *oif, enum oonf_log_source log_src) {
-  return os_fd_generic_join_mcast_recv(sock, multicast, oif, log_src);
+    const struct os_interface *os_if, enum oonf_log_source log_src) {
+  return os_fd_generic_join_mcast_recv(sock, multicast, os_if, log_src);
 }
 
 /**
  * Redirect to generic mcast sender join call
  * @param sock socket representation
  * @param multicast sending multicast group to join
- * @param oif outgoing interface for multicast,
+ * @param os_if outgoing interface for multicast,
  *   NULL if not interface specific
  * @param loop true if multicast should be locally looped
  * @param log_src logging source for error messages
@@ -197,8 +197,8 @@ os_fd_join_mcast_recv(struct os_fd *sock, const struct netaddr *multicast,
  */
 static INLINE int
 os_fd_join_mcast_send(struct os_fd *sock, const struct netaddr *multicast,
-    const struct os_interface_data *oif, bool loop, enum oonf_log_source log_src) {
-  return os_fd_generic_join_mcast_send(sock, multicast, oif, loop, log_src);
+    const struct os_interface *os_if, bool loop, enum oonf_log_source log_src) {
+  return os_fd_generic_join_mcast_send(sock, multicast, os_if, loop, log_src);
 }
 /**
  * Redirect to generic set_dscp call
@@ -516,7 +516,7 @@ os_fd_sendto(struct os_fd *sock, const void *buf, size_t length, const union net
  */
 static INLINE ssize_t
 os_fd_recvfrom(struct os_fd *sock, void *buf, size_t length, union netaddr_socket *source,
-    const struct os_interface_data *interf __attribute__((unused))) {
+    const struct os_interface *interf __attribute__((unused))) {
   socklen_t len = sizeof(*source);
   return recvfrom(sock->fd, buf, length, 0, &source->std, &len);
 }
@@ -528,7 +528,7 @@ os_fd_recvfrom(struct os_fd *sock, void *buf, size_t length, union netaddr_socke
  * @return -1 if an error happened, 0 otherwise
  */
 static INLINE int
-os_fd_bindto_interface(struct os_fd *sock, struct os_interface_data *data) {
+os_fd_bindto_interface(struct os_fd *sock, struct os_interface *data) {
   return setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE, data->name, strlen(data->name) + 1);
 }
 
index c66ebcf..71739dd 100644 (file)
 #include <time.h>
 
 #include "common/common_types.h"
+#include "common/avl.h"
+#include "common/avl_comp.h"
 #include "common/string.h"
+#include "core/oonf_cfg.h"
+#include "core/oonf_main.h"
 #include "core/oonf_subsystem.h"
+#include "subsystems/oonf_class.h"
+#include "subsystems/oonf_timer.h"
 #include "subsystems/os_system.h"
 
 #include "subsystems/os_interface.h"
 /* prototypes */
 static int _init(void);
 static void _cleanup(void);
+static void _early_cfg_init(void);
+
+static int _init_mesh(struct os_interface *os_if);
+static void _cleanup_mesh(struct os_interface *os_if);
+
+static void _query_interface_links(void);
+static void _query_interface_addresses(void);
 
 static void _cb_rtnetlink_message(struct nlmsghdr *hdr);
 static void _cb_rtnetlink_error(uint32_t seq, int error);
 static void _cb_rtnetlink_done(uint32_t seq);
 static void _cb_rtnetlink_timeout(void);
-static void _address_finished(struct os_interface_address *addr, int error);
+static void _cb_query_error(uint32_t seq, int error);
+static void _cb_query_done(uint32_t seq);
+static void _cb_query_timeout(void);
+static void _address_finished(
+    struct os_interface_ip_change *addr, int error);
 
 static void _activate_if_routing(void);
 static void _deactivate_if_routing(void);
 static int _os_linux_writeToFile(const char *file, char *old, char value);
-static unsigned _os_linux_get_base_ifindex(const char *interf);
-
-/* ioctl socket */
-static int _ioctl_fd = -1;
 
-/* list of interface change listeners */
-static struct list_entity _ifchange_listener;
+static void _cb_interface_changed(struct oonf_timer_instance *);
+static int _handle_unused_parameter(const char *arg);
 
 /* subsystem definition */
 static const char *_dependencies[] = {
+  OONF_CLASS_SUBSYSTEM,
+  OONF_TIMER_SUBSYSTEM,
   OONF_OS_SYSTEM_SUBSYSTEM,
 };
 
@@ -130,10 +145,11 @@ static struct oonf_subsystem _oonf_os_interface_subsystem = {
   .dependencies_count = ARRAYSIZE(_dependencies),
   .init = _init,
   .cleanup = _cleanup,
+  .early_cfg_init = _early_cfg_init,
 };
 DECLARE_OONF_PLUGIN(_oonf_os_interface_subsystem);
 
-/* built in rtnetlink receiver */
+/* rtnetlink receiver for interface and address events */
 static struct os_system_netlink _rtnetlink_receiver = {
   .name = "interface snooper",
   .used_by = &_oonf_os_interface_subsystem,
@@ -149,6 +165,20 @@ static const uint32_t _rtnetlink_mcast[] = {
   RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR
 };
 
+static struct os_system_netlink _rtnetlink_if_query = {
+  .name = "interface query",
+  .used_by = &_oonf_os_interface_subsystem,
+  .cb_message = _cb_rtnetlink_message,
+  .cb_error = _cb_query_error,
+  .cb_done = _cb_query_done,
+  .cb_timeout = _cb_query_timeout,
+};
+
+static bool _link_query_in_progress = false;
+static bool _address_query_in_progress = false;
+static bool _trigger_link_query = false;
+static bool _trigger_address_query = false;
+
 /* global procfile state before initialization */
 static char _original_rp_filter;
 static char _original_icmp_redirect;
@@ -161,34 +191,60 @@ static int _mesh_count = 0;
 /* kernel version check */
 static bool _is_kernel_2_6_31_or_better;
 
+/* interface data handling */
+static struct oonf_class _interface_data_class = {
+  .name = "network interface data",
+  .size = sizeof(struct os_interface),
+};
+
+static struct oonf_class _interface_class = {
+  .name = "network interface",
+  .size = sizeof(struct os_interface_listener),
+};
+
+static struct oonf_class _interface_ip_class = {
+  .name = "network interface ip",
+  .size = sizeof(struct os_interface_ip),
+};
+
+static struct oonf_timer_class _interface_change_timer = {
+  .name = "interface change",
+  .callback = _cb_interface_changed,
+};
+
+static struct avl_tree _interface_data_tree;
+static const char _ANY_INTERFACE[] = OS_INTERFACE_ANY;
+
 /**
  * Initialize os-specific subsystem
  * @return -1 if an error happened, 0 otherwise
  */
 static int
 _init(void) {
-  _ioctl_fd = socket(AF_INET, SOCK_DGRAM, 0);
-  if (_ioctl_fd == -1) {
-    OONF_WARN(LOG_OS_INTERFACE, "Cannot open ioctl socket: %s (%d)",
-        strerror(errno), errno);
+  if (os_system_linux_netlink_add(&_rtnetlink_receiver, NETLINK_ROUTE)) {
     return -1;
   }
 
-  if (os_system_linux_netlink_add(&_rtnetlink_receiver, NETLINK_ROUTE)) {
-    close(_ioctl_fd);
+  if (os_system_linux_netlink_add(&_rtnetlink_if_query, NETLINK_ROUTE)) {
+    os_system_linux_netlink_remove(&_rtnetlink_receiver);
     return -1;
   }
 
   if (os_system_linux_netlink_add_mc(&_rtnetlink_receiver, _rtnetlink_mcast, ARRAYSIZE(_rtnetlink_mcast))) {
     os_system_linux_netlink_remove(&_rtnetlink_receiver);
-    close(_ioctl_fd);
+    os_system_linux_netlink_remove(&_rtnetlink_if_query);
     return -1;
   }
 
-  list_init_head(&_ifchange_listener);
   list_init_head(&_rtnetlink_feedback);
+  avl_init(&_interface_data_tree, avl_comp_strcasecmp, false);
+  oonf_class_add(&_interface_data_class);
+  oonf_class_add(&_interface_ip_class);
+  oonf_class_add(&_interface_class);
+  oonf_timer_add(&_interface_change_timer);
 
   _is_kernel_2_6_31_or_better = os_system_linux_is_minimal_kernel(2,6,31);
+
   return 0;
 }
 
@@ -197,46 +253,170 @@ _init(void) {
  */
 static void
 _cleanup(void) {
+  struct os_interface_listener *if_listener, *if_listener_it;
+  struct os_interface *os_if, *os_if_it;
+
+  avl_for_each_element_safe(&_interface_data_tree, os_if, _node, os_if_it) {
+    list_for_each_element_safe(&os_if->_listeners, if_listener, _node, if_listener_it) {
+      os_interface_linux_remove(if_listener);
+    }
+  }
+
+  oonf_timer_remove(&_interface_change_timer);
+  oonf_class_remove(&_interface_ip_class);
+  oonf_class_remove(&_interface_data_class);
+  oonf_class_remove(&_interface_class);
+
+  os_system_linux_netlink_remove(&_rtnetlink_if_query);
   os_system_linux_netlink_remove(&_rtnetlink_receiver);
-  close(_ioctl_fd);
+}
+
+static
+void _early_cfg_init(void) {
+  oonf_main_set_parameter_handler(_handle_unused_parameter);
 }
 
 /**
  * Add an interface event listener to the operation system
- * @param listener interface listener
+ * @param if_listener network interface listener
  */
-void
-os_interface_linux_listener_add(struct os_interface_if_listener *listener) {
-  list_add_tail(&_ifchange_listener, &listener->_node);
+struct os_interface *
+os_interface_linux_add(struct os_interface_listener *if_listener) {
+  struct os_interface *data;
+
+  if (if_listener->data) {
+    /* interface is already hooked up to data */
+    return if_listener->data;
+  }
+
+  if (!if_listener->name || !if_listener->name[0]) {
+    if_listener->name = _ANY_INTERFACE;
+  }
+
+  data = avl_find_element(&_interface_data_tree, if_listener->name, data, _node);
+  if (!data) {
+    data = oonf_class_malloc(&_interface_data_class);
+    if (!data) {
+      return NULL;
+    }
+
+    OONF_INFO(LOG_OS_INTERFACE, "Add interface to tracking: %s", if_listener->name);
+
+    /* hook into interface data tree */
+    strscpy(data->name, if_listener->name, IF_NAMESIZE);
+    data->_node.key = data->name;
+    avl_insert(&_interface_data_tree, &data->_node);
+
+    /* initialize list/tree */
+    avl_init(&data->addresses, avl_comp_netaddr, false);
+    list_init_head(&data->_listeners);
+
+    /* initialize change timer */
+    data->_change_timer.class = &_interface_change_timer;
+
+    /* check if this is the unspecified interface "any" */
+    if (strcmp(data->name, _ANY_INTERFACE) == 0) {
+      data->if_type = OS_IFTYPE_ANY;
+    }
+
+    /* trigger new queries */
+    _trigger_link_query = true;
+    _trigger_address_query = true;
+
+    _query_interface_links();
+  }
+
+  /* hook into interface data */
+  if_listener->data = data;
+  list_add_tail(&data->_listeners, &if_listener->_node);
+
+  if (if_listener->mesh && if_listener->name != _ANY_INTERFACE) {
+    if (!data->_internal.mesh_counter) {
+      _init_mesh(data);
+    }
+    data->_internal.mesh_counter++;
+  }
+
+  /* trigger interface change listener if necessary */
+  if_listener->_dirty = true;
+  oonf_timer_start(&data->_change_timer, 200);
+
+  return data;
 }
 
 /**
  * Remove an interface event listener to the operation system
- * @param listener interface listener
+ * @param if_listener network interface listener
  */
 void
-os_interface_linux_listener_remove(struct os_interface_if_listener *listener) {
-  list_remove(&listener->_node);
+os_interface_linux_remove(struct os_interface_listener *if_listener) {
+  struct os_interface *data;
+
+  if (!if_listener->data) {
+    /* interface not hooked up to data */
+    return;
+  }
+
+  OONF_INFO(LOG_OS_INTERFACE, "Remove interface from tracking: %s", if_listener->name);
+
+  if (if_listener->mesh) {
+    if_listener->data->_internal.mesh_counter--;
+    if (!if_listener->data->_internal.mesh_counter) {
+      _cleanup_mesh(if_listener->data);
+    }
+  }
+
+  /* unhook from interface data */
+  data = if_listener->data;
+  if_listener->data = NULL;
+  list_remove(&if_listener->_node);
+
+  if (list_is_empty(&data->_listeners)) {
+    oonf_timer_stop(&data->_change_timer);
+    avl_remove(&_interface_data_tree, &data->_node);
+    oonf_class_free(&_interface_data_class, data);
+  }
 }
 
+/**
+ * @return tree of os interfaces
+ */
+struct avl_tree *
+os_interface_linux_get_tree(void) {
+  return &_interface_data_tree;
+}
+
+/**
+ * Trigger the event handler of an interface listener
+ * @param if_listener network interface listener
+ */
+void
+os_interface_linux_trigger_handler(struct os_interface_listener *if_listener) {
+  if_listener->_dirty = true;
+  if (!oonf_timer_is_active(&if_listener->data->_change_timer)) {
+    oonf_timer_start(&if_listener->data->_change_timer,
+        OS_INTERFACE_CHANGE_TRIGGER_INTERVAL);
+  }
+}
 /**
  * Set interface up or down
- * @param dev pointer to name of interface
+ * @param os_if network interface
  * @param up true if interface should be up, false if down
  * @return -1 if an error happened, 0 otherwise
  */
 int
-os_interface_linux_state_set(const char *dev, bool up) {
+os_interface_linux_state_set(struct os_interface *os_if, bool up) {
   int oldflags;
   struct ifreq ifr;
 
   memset(&ifr, 0, sizeof(ifr));
-  strscpy(ifr.ifr_name, dev, IF_NAMESIZE);
+  strscpy(ifr.ifr_name, os_if->name, IF_NAMESIZE);
 
-  if (ioctl(_ioctl_fd, SIOCGIFFLAGS, &ifr) < 0) {
+  if (ioctl(os_system_linux_linux_get_ioctl_fd(AF_INET),
+      SIOCGIFFLAGS, &ifr) < 0) {
     OONF_WARN(LOG_OS_INTERFACE,
         "ioctl SIOCGIFFLAGS (get flags) error on device %s: %s (%d)\n",
-        dev, strerror(errno), errno);
+        os_if->name, strerror(errno), errno);
     return -1;
   }
 
@@ -253,10 +433,11 @@ os_interface_linux_state_set(const char *dev, bool up) {
     return 0;
   }
 
-  if (ioctl(_ioctl_fd, SIOCSIFFLAGS, &ifr) < 0) {
+  if (ioctl(os_system_linux_linux_get_ioctl_fd(AF_INET),
+      SIOCSIFFLAGS, &ifr) < 0) {
     OONF_WARN(LOG_OS_INTERFACE,
         "ioctl SIOCSIFFLAGS (set flags %s) error on device %s: %s (%d)\n",
-        up ? "up" : "down", dev, strerror(errno), errno);
+        up ? "up" : "down", os_if->name, strerror(errno), errno);
     return -1;
   }
   return 0;
@@ -269,7 +450,8 @@ os_interface_linux_state_set(const char *dev, bool up) {
  *   0 otherwise
  */
 int
-os_interface_linux_address_set(struct os_interface_address *addr) {
+os_interface_linux_address_set(
+    struct os_interface_ip_change *addr) {
   uint8_t buffer[UIO_MAXIOV];
   struct nlmsghdr *msg;
   struct ifaddrmsg *ifaddrreq;
@@ -325,7 +507,7 @@ os_interface_linux_address_set(struct os_interface_address *addr) {
  * @param addr interface address change request
  */
 void
-os_interface_linux_address_interrupt(struct os_interface_address *addr) {
+os_interface_linux_address_interrupt(struct os_interface_ip_change *addr) {
   if (list_is_node_added(&addr->_internal._node)) {
     /* remove first to prevent any kind of recursive cleanup */
     list_remove(&addr->_internal._node);
@@ -338,12 +520,12 @@ os_interface_linux_address_interrupt(struct os_interface_address *addr) {
 
 /**
  * Set the mac address of an interface
- * @param name name of interface
+ * @param os_if network interface
  * @param mac mac address
  * @return -1 if an error happened, 0 otherwise
  */
 int
-os_interface_linux_mac_set_by_name(const char *name, struct netaddr *mac) {
+os_interface_linux_mac_set(struct os_interface *os_if, struct netaddr *mac) {
   struct ifreq if_req;
   struct netaddr_str nbuf;
 
@@ -354,225 +536,161 @@ os_interface_linux_mac_set_by_name(const char *name, struct netaddr *mac) {
   }
 
   memset(&if_req, 0, sizeof(if_req));
-  strscpy(if_req.ifr_name, name, IF_NAMESIZE);
+  strscpy(if_req.ifr_name, os_if->name, IF_NAMESIZE);
 
   if_req.ifr_addr.sa_family = ARPHRD_ETHER;
   netaddr_to_binary(&if_req.ifr_addr.sa_data, mac, 6);
 
   if (ioctl(os_system_linux_linux_get_ioctl_fd(AF_INET), SIOCSIFHWADDR, &if_req) < 0) {
     OONF_WARN(LOG_OS_INTERFACE, "Could not set mac address of '%s': %s (%d)",
-        name, strerror(errno), errno);
+        os_if->name, strerror(errno), errno);
     return -1;
   }
   return 0;
 }
 
 /**
- * Updates the data of an interface.
- * The interface data object will be completely overwritten
- * @param ifdata pointer to an interface data object
- * @param name name of interface
+ * Initialize interface for mesh usage
+ * @param os_if network interface data
  * @return -1 if an error happened, 0 otherwise
  */
-int
-os_interface_linux_update(struct os_interface_data *ifdata,
-    const char *name) {
-  struct ifreq ifr;
-  struct ifaddrs *ifaddrs;
-  struct ifaddrs *ifa;
-  size_t addrcount;
-  union netaddr_socket *sock;
-  struct netaddr *addr, *prefix, netmask;
-#ifdef OONF_LOG_INFO
-  struct netaddr_str nbuf1;
-#endif
-#ifdef OONF_LOG_DEBUG_INFO
-  struct netaddr_str nbuf2, nbuf3;
-#endif
+static int
+_init_mesh(struct os_interface *os_if) {
+  char procfile[FILENAME_MAX];
+  char old_redirect = 0, old_spoof = 0;
 
-  /* cleanup data structure */
-  if (ifdata->addresses) {
-    free(ifdata->addresses);
+  switch (os_if->if_type) {
+    case OS_IFTYPE_ANY:
+    case OS_IFTYPE_LOOPBACK:
+      /* ignore loopback and unspecific interface*/
+      return 0;
+    default:
+      break;
   }
 
-  memset(ifdata, 0, sizeof(*ifdata));
-  strscpy(ifdata->name, name, sizeof(ifdata->name));
-
-  /* get interface index */
-  ifdata->index = if_nametoindex(name);
-  if (ifdata->index == 0) {
-    /* interface is not there at the moment */
-    return 0;
+  /* handle global ip_forward setting */
+  _mesh_count++;
+  if (_mesh_count == 1) {
+    _activate_if_routing();
   }
 
-  ifdata->base_index = _os_linux_get_base_ifindex(name);
-
-  memset(&ifr, 0, sizeof(ifr));
-  strscpy(ifr.ifr_name, ifdata->name, IF_NAMESIZE);
+  /* Generate the procfile name */
+  snprintf(procfile, sizeof(procfile), PROC_IF_REDIRECT, os_if->name);
 
-  if (ioctl(os_system_linux_linux_get_ioctl_fd(AF_INET), SIOCGIFFLAGS, &ifr) < 0) {
-    OONF_WARN(LOG_OS_INTERFACE,
-        "ioctl SIOCGIFFLAGS (get flags) error on device %s: %s (%d)\n",
-        ifdata->name, strerror(errno), errno);
-    return -1;
+  if (_os_linux_writeToFile(procfile, &old_redirect, '0')) {
+    OONF_WARN(LOG_OS_INTERFACE, "WARNING! Could not disable ICMP redirects! "
+        "You should manually ensure that ICMP redirects are disabled!");
   }
 
-  ifdata->up = (ifr.ifr_flags & IFF_UP) == IFF_UP;
-  ifdata->loopback = (ifr.ifr_flags & IFF_LOOPBACK) != 0;
-
-  memset(&ifr, 0, sizeof(ifr));
-  strscpy(ifr.ifr_name, ifdata->name, IF_NAMESIZE);
+  /* Generate the procfile name */
+  snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, os_if->name);
 
-  if (ioctl(os_system_linux_linux_get_ioctl_fd(AF_INET), SIOCGIFHWADDR, &ifr) < 0) {
-    OONF_WARN(LOG_OS_INTERFACE,
-        "ioctl SIOCGIFHWADDR (get flags) error on device %s: %s (%d)\n",
-        ifdata->name, strerror(errno), errno);
-    return -1;
+  if (_os_linux_writeToFile(procfile, &old_spoof, '0')) {
+    OONF_WARN(LOG_OS_INTERFACE, "WARNING! Could not disable the IP spoof filter! "
+        "You should mannually ensure that IP spoof filtering is disabled!");
   }
 
-  netaddr_from_binary(&ifdata->mac, ifr.ifr_hwaddr.sa_data, 6, AF_MAC48);
-  OONF_INFO(LOG_OS_INTERFACE, "Interface %s has mac address %s",
-      ifdata->name, netaddr_to_string(&nbuf1, &ifdata->mac));
-
-  /* get ip addresses */
-  ifaddrs = NULL;
-  addrcount = 0;
-
-  if (getifaddrs(&ifaddrs)) {
-    OONF_WARN(LOG_OS_INTERFACE,
-        "getifaddrs() failed: %s (%d)", strerror(errno), errno);
-    return -1;
-  }
+  os_if->_internal._original_state = (old_redirect << 8) | (old_spoof);
+  return 0;
+}
 
-  for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-    if (strcmp(ifdata->name, ifa->ifa_name) == 0 && ifa->ifa_addr != NULL &&
-        (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6)) {
-      addrcount++;
-    }
-  }
+/**
+ * Query a dump of all interface link data
+ */
+static void
+_query_interface_links(void) {
+  uint8_t buffer[UIO_MAXIOV];
+  struct nlmsghdr *msg;
+  struct ifinfomsg *ifi;
+#if defined(OONF_LOG_DEBUG_INFO)
+#endif
 
-  ifdata->addresses = calloc(addrcount*2, sizeof(struct netaddr));
-  if (ifdata->addresses == NULL) {
-    OONF_WARN(LOG_OS_INTERFACE,
-        "Cannot allocate memory for interface %s with %"PRINTF_SIZE_T_SPECIFIER" prefixes",
-        ifdata->name, addrcount);
-    freeifaddrs(ifaddrs);
-    return -1;
+  if (_link_query_in_progress || _address_query_in_progress) {
+    return;
   }
 
-  ifdata->prefixes = &ifdata->addresses[addrcount];
-
-  ifdata->if_v4 = &NETADDR_UNSPEC;
-  ifdata->if_v6 = &NETADDR_UNSPEC;
-  ifdata->linklocal_v6_ptr = &NETADDR_UNSPEC;
+  OONF_DEBUG(LOG_OS_INTERFACE, "Request all interfaces");
 
-  for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-    if (strcmp(ifdata->name, ifa->ifa_name) == 0 && ifa->ifa_addr != NULL &&
-        (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6)) {
-      sock = (union netaddr_socket *)ifa->ifa_addr;
-      addr = &ifdata->addresses[ifdata->addrcount];
+  _trigger_link_query = false;
 
-      /* get address of interface */
-      if (netaddr_from_socket(addr, sock) == 0) {
-        ifdata->addrcount++;
+  /* get pointers for netlink message */
+  msg = (void *)&buffer[0];
 
-        sock = (union netaddr_socket *)ifa->ifa_netmask;
-        prefix = &ifdata->prefixes[ifdata->prefixcount];
+  /* get link level data */
+  memset(buffer, 0, sizeof(buffer));
+  msg->nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+  msg->nlmsg_type = RTM_GETLINK;
 
-        /* get corresponding prefix if possible */
-        if (!netaddr_from_socket(&netmask, sock)) {
-          if (!netaddr_create_prefix(prefix, addr, &netmask, false)) {
-            OONF_DEBUG(LOG_OS_INTERFACE, "Address %s and Netmask %s produce prefix %s",
-                netaddr_to_string(&nbuf1, addr),
-                netaddr_to_string(&nbuf2, &netmask),
-                netaddr_to_string(&nbuf3, prefix));
-            ifdata->prefixcount++;
-          }
-        }
+  /* set length of netlink message with ifinfomsg payload */
+  msg->nlmsg_len = NLMSG_LENGTH(sizeof(*ifi));
 
-        if (netaddr_get_address_family(addr) == AF_INET) {
-          if (!netaddr_is_in_subnet(&NETADDR_IPV4_MULTICAST, addr)) {
-            ifdata->if_v4 = addr;
-          }
-        }
-        else if (netaddr_get_address_family(addr) == AF_INET6) {
-          if (netaddr_is_in_subnet(&NETADDR_IPV6_LINKLOCAL, addr)) {
-            ifdata->linklocal_v6_ptr = addr;
-          }
-          else if (!(netaddr_is_in_subnet(&NETADDR_IPV6_MULTICAST, addr)
-              || netaddr_is_in_subnet(&NETADDR_IPV6_IPV4COMPATIBLE, addr)
-              || netaddr_is_in_subnet(&NETADDR_IPV6_IPV4MAPPED, addr))) {
-            ifdata->if_v6 = addr;
-          }
-        }
-      }
-    }
-  }
+  ifi = NLMSG_DATA(msg);
+  ifi->ifi_family = AF_NETLINK;
 
-  freeifaddrs(ifaddrs);
-  return 0;
+  /* we don't care for the sequence number */
+  os_system_linux_netlink_send(&_rtnetlink_if_query, msg);
 }
 
 /**
- * Initialize interface for mesh usage
- * @param interf pointer to interface object
- * @return -1 if an error happened, 0 otherwise
+ * Query a dump of all interface link data
  */
-int
-os_interface_linux_init_mesh(struct os_interface *interf) {
-  char procfile[FILENAME_MAX];
-  char old_redirect = 0, old_spoof = 0;
+static void
+_query_interface_addresses(void) {
+  uint8_t buffer[UIO_MAXIOV];
+  struct nlmsghdr *msg;
+  struct ifaddrmsg *ifa;
+#if defined(OONF_LOG_DEBUG_INFO)
+#endif
 
-  if (interf->data.loopback) {
-    /* ignore loopback */
-    return 0;
+  if (_link_query_in_progress || _address_query_in_progress) {
+    return;
   }
 
-  /* handle global ip_forward setting */
-  _mesh_count++;
-  if (_mesh_count == 1) {
-    _activate_if_routing();
-  }
+  _trigger_address_query = false;
 
-  /* Generate the procfile name */
-  snprintf(procfile, sizeof(procfile), PROC_IF_REDIRECT, interf->data.name);
+  OONF_DEBUG(LOG_OS_INTERFACE, "Request all interfaces");
 
-  if (_os_linux_writeToFile(procfile, &old_redirect, '0')) {
-    OONF_WARN(LOG_OS_INTERFACE, "WARNING! Could not disable ICMP redirects! "
-        "You should manually ensure that ICMP redirects are disabled!");
-  }
+  /* get pointers for netlink message */
+  msg = (void *)&buffer[0];
 
-  /* Generate the procfile name */
-  snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, interf->data.name);
+  /* get IP level data */
+  memset(buffer, 0, sizeof(buffer));
+  msg->nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+  msg->nlmsg_type = RTM_GETADDR;
 
-  if (_os_linux_writeToFile(procfile, &old_spoof, '0')) {
-    OONF_WARN(LOG_OS_INTERFACE, "WARNING! Could not disable the IP spoof filter! "
-        "You should mannually ensure that IP spoof filtering is disabled!");
-  }
+  /* set length of netlink message with ifaddrmsg payload */
+  msg->nlmsg_len = NLMSG_LENGTH(sizeof(*ifa));
 
-  interf->_original_state = (old_redirect << 8) | (old_spoof);
-  return 0;
+  ifa = NLMSG_DATA(msg);
+  ifa->ifa_family = AF_UNSPEC;
+
+  /* we don't care for the sequence number */
+  os_system_linux_netlink_send(&_rtnetlink_if_query, msg);
 }
 
 /**
  * Cleanup interface after mesh usage
- * @param interf pointer to interface object
+ * @param data network interface data
  */
-void
-os_interface_linux_cleanup_mesh(struct os_interface *interf) {
+static void
+_cleanup_mesh(struct os_interface *os_if) {
   char restore_redirect, restore_spoof;
   char procfile[FILENAME_MAX];
 
-  if (interf->data.loopback) {
-    /* ignore loopback */
-    return;
+  switch (os_if->if_type) {
+    case OS_IFTYPE_ANY:
+    case OS_IFTYPE_LOOPBACK:
+      /* ignore loopback and unspecific interface*/
+      return;
+    default:
+      break;
   }
 
-  restore_redirect = (interf->_original_state >> 8) & 255;
-  restore_spoof = (interf->_original_state & 255);
+  restore_redirect = (os_if->_internal._original_state >> 8) & 255;
+  restore_spoof = (os_if->_internal._original_state & 255);
 
   /* Generate the procfile name */
-  snprintf(procfile, sizeof(procfile), PROC_IF_REDIRECT, interf->data.name);
+  snprintf(procfile, sizeof(procfile), PROC_IF_REDIRECT, os_if->name);
 
   if (_os_linux_writeToFile(procfile, NULL, restore_redirect) != 0) {
     OONF_WARN(LOG_OS_INTERFACE, "Could not restore ICMP redirect flag %s to %c",
@@ -580,7 +698,7 @@ os_interface_linux_cleanup_mesh(struct os_interface *interf) {
   }
 
   /* Generate the procfile name */
-  snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, interf->data.name);
+  snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, os_if->name);
 
   if (_os_linux_writeToFile(procfile, NULL, restore_spoof) != 0) {
     OONF_WARN(LOG_OS_INTERFACE, "Could not restore IP spoof flag %s to %c",
@@ -593,51 +711,10 @@ os_interface_linux_cleanup_mesh(struct os_interface *interf) {
     _deactivate_if_routing();
   }
 
-  interf->_original_state = 0;
+  os_if->_internal._original_state = 0;
   return;
 }
 
-/**
- * Get the base interface index of a VLAN interface
- * @param interf name of VLAN interface
- * @return interface index of base interface
- */
-static unsigned
-_os_linux_get_base_ifindex(const char *interf) {
-  char sysfile[FILENAME_MAX];
-  char ifnumber[11];
-  int fd;
-  ssize_t len;
-
-  /* Generate the sysfs name */
-  snprintf(sysfile, sizeof(sysfile), SYSFS_BASE_IFINDEX, interf);
-
-  if ((fd = open(sysfile, O_RDONLY)) < 0) {
-    OONF_WARN(LOG_OS_INTERFACE,
-      "Error, cannot open sysfs entry %s: %s (%d)\n",
-      sysfile, strerror(errno), errno);
-    return 0;
-  }
-
-  if ((len = read(fd, &ifnumber, sizeof(ifnumber))) < 0) {
-    OONF_WARN(LOG_OS_INTERFACE,
-      "Error, cannot read proc entry %s: %s (%d)\n",
-      sysfile, strerror(errno), errno);
-    close(fd);
-    return 0;
-  }
-
-  if (len >= (ssize_t)sizeof(ifnumber)) {
-    OONF_WARN(LOG_OS_INTERFACE, "Content of %s too long", sysfile);
-    close(fd);
-    return 0;
-  }
-
-  ifnumber[len] = 0;
-  close(fd);
-  return atoi(ifnumber);
-}
-
 /**
  * Set the required settings to allow multihop mesh routing
  */
@@ -759,6 +836,257 @@ _os_linux_writeToFile(const char *file, char *old, char value) {
   return 0;
 }
 
+/**
+ * Trigger all change listeners of a network interface
+ * @param os_if network interface
+ */
+static void
+_trigger_if_change(struct os_interface *os_if) {
+  struct os_interface_listener *if_listener;
+
+  if (!oonf_timer_is_active(&os_if->_change_timer)) {
+    /* inform listeners the interface changed */
+    oonf_timer_start(&os_if->_change_timer, 200);
+
+    list_for_each_element(&os_if->_listeners, if_listener, _node) {
+      /* each interface should be informed */
+      if_listener->_dirty = true;
+    }
+  }
+}
+
+/**
+ * Trigger all change listeners of a network interface.
+ * Trigger also all change listeners of the wildcard interface "any"
+ * @param os_if network interface
+ */
+static void
+_trigger_if_change_including_any(struct os_interface *os_if) {
+  _trigger_if_change(os_if);
+
+  os_if = avl_find_element(
+      &_interface_data_tree, OS_INTERFACE_ANY, os_if, _node);
+  if (os_if) {
+    _trigger_if_change(os_if);
+  }
+}
+
+/**
+ * Parse an incoming LINK information from netlink
+ * @param ifname interface name
+ * @param msg netlink message
+ */
+static void
+_link_parse_nlmsg(const char *ifname, struct nlmsghdr *msg) {
+  struct ifinfomsg *ifi_msg;
+  struct rtattr *ifi_attr;
+  int ifi_len;
+  struct netaddr addr;
+  struct netaddr_str nbuf;
+  struct os_interface *ifdata;
+  int iflink;
+
+  ifi_msg = NLMSG_DATA(msg);
+  ifi_attr = (struct rtattr *) IFLA_RTA(ifi_msg);
+  ifi_len = RTM_PAYLOAD(msg);
+
+  ifdata = avl_find_element(&_interface_data_tree, ifname, ifdata, _node);
+  if (!ifdata) {
+    return;
+  }
+
+  ifdata->up = (ifi_msg->ifi_flags & IFF_UP) != 0;
+  if ((ifi_msg->ifi_flags & IFF_LOOPBACK) != 0) {
+    ifdata->if_type = OS_IFTYPE_LOOPBACK;
+  }
+
+  OONF_DEBUG(LOG_OS_INTERFACE, "Parse IFI_LINK %s (%u) is %s",
+      ifname, ifi_msg->ifi_index, ifdata->up ? "up" : "down");
+
+  ifdata->index = ifi_msg->ifi_index;
+
+  for(; RTA_OK(ifi_attr, ifi_len); ifi_attr = RTA_NEXT(ifi_attr,ifi_len)) {
+    switch(ifi_attr->rta_type) {
+      case IFLA_ADDRESS:
+        netaddr_from_binary(&addr, RTA_DATA(ifi_attr), RTA_PAYLOAD(ifi_attr), AF_MAC48);
+        OONF_DEBUG(LOG_OS_INTERFACE, "Link: %s", netaddr_to_string(&nbuf, &addr));
+
+        if (msg->nlmsg_type == RTM_NEWLINK) {
+          memcpy(&ifdata->mac, &addr, sizeof(addr));
+        }
+        break;
+      case IFLA_LINK:
+        memcpy(&iflink, RTA_DATA(ifi_attr), RTA_PAYLOAD(ifi_attr));
+
+        OONF_INFO(LOG_OS_INTERFACE, "Base interface index for %s (%u): %u",
+            ifdata->name, ifdata->index, iflink);
+        ifdata->base_index = iflink;
+        break;
+      default:
+        //OONF_DEBUG(LOG_OS_INTERFACE, "ifi_attr_type: %u", ifi_attr->rta_type);
+        break;
+    }
+  }
+
+  _trigger_if_change_including_any(ifdata);
+}
+
+/**
+ * Update the links for routable/ll addresses of a network interface
+ * @param os_if network interface
+ */
+static void
+_update_address_shortcuts(struct os_interface *os_if) {
+  struct os_interface_ip *ip;
+  bool ipv4_ll, ipv6_ll, ipv4_routable, ipv6_routable;
+
+  /* update address shortcuts */
+  os_if->if_v4 = &NETADDR_UNSPEC;
+  os_if->if_v6 = &NETADDR_UNSPEC;
+  os_if->if_linklocal_v4 = &NETADDR_UNSPEC;
+  os_if->if_linklocal_v6 = &NETADDR_UNSPEC;
+
+  avl_for_each_element(&os_if->addresses, ip, _node) {
+    ipv4_ll = netaddr_is_in_subnet(&ip->address, &NETADDR_IPV4_LINKLOCAL);
+    ipv6_ll = netaddr_is_in_subnet(&ip->address, &NETADDR_IPV6_LINKLOCAL);
+
+    ipv4_routable = !ipv4_ll
+        && netaddr_get_address_family(&ip->address) == AF_INET
+        && !netaddr_is_in_subnet(&ip->address, &NETADDR_IPV4_LOOPBACK_NET)
+        && !netaddr_is_in_subnet(&ip->address, &NETADDR_IPV4_MULTICAST);
+    ipv6_routable = !ipv4_ll
+        && (netaddr_is_in_subnet(&ip->address, &NETADDR_IPV6_ULA)
+            || netaddr_is_in_subnet(&ip->address, &NETADDR_IPV6_GLOBAL));
+
+    if (netaddr_is_unspec(os_if->if_v4) && ipv4_routable) {
+      os_if->if_v4 = &ip->address;
+    }
+    if (netaddr_is_unspec(os_if->if_v6) && ipv6_routable) {
+      os_if->if_v6 = &ip->address;
+    }
+    if (netaddr_is_unspec(os_if->if_linklocal_v4) && ipv4_ll) {
+      os_if->if_linklocal_v4 = &ip->address;
+    }
+    if (netaddr_is_unspec(os_if->if_linklocal_v6) && ipv6_ll) {
+      os_if->if_linklocal_v6 = &ip->address;
+    }
+  }
+}
+
+/**
+ * Add an IP address/prefix to a network interface
+ * @param os_if network interface
+ * @param prefixed_addr full IP address with prefix length
+ */
+static void
+_add_address(struct os_interface *os_if, struct netaddr *prefixed_addr) {
+  struct os_interface_ip *ip;
+#if defined(OONF_LOG_DEBUG_INFO)
+  struct netaddr_str nbuf;
+#endif
+
+  ip = avl_find_element(&os_if->addresses, prefixed_addr, ip, _node);
+  if (!ip) {
+    ip = oonf_class_malloc(&_interface_ip_class);
+    if (!ip) {
+      return;
+    }
+
+    /* establish key and add to tree */
+    memcpy(&ip->prefixed_addr, prefixed_addr, sizeof(*prefixed_addr));
+    ip->_node.key = &ip->prefixed_addr;
+    avl_insert(&os_if->addresses, &ip->_node);
+
+    /* add back pointer */
+    ip->interf = os_if;
+  }
+
+  OONF_INFO(LOG_OS_INTERFACE, "Add address to %s: %s",
+      os_if->name, netaddr_to_string(&nbuf, prefixed_addr));
+
+  /* copy sanitized addresses */
+  memcpy(&ip->address, prefixed_addr, sizeof(*prefixed_addr));
+  netaddr_set_prefix_length(&ip->address, netaddr_get_maxprefix(&ip->address));
+  netaddr_truncate(&ip->prefix, prefixed_addr);
+}
+
+/**
+ * Remove an IP address/prefix from a network interface
+ * @param os_if network interface
+ * @param prefixed_addr full IP address with prefix length
+ */
+static void
+_remove_address(struct os_interface *os_if, struct netaddr *prefixed_addr) {
+  struct os_interface_ip *ip;
+#if defined(OONF_LOG_DEBUG_INFO)
+  struct netaddr_str nbuf;
+#endif
+
+  ip = avl_find_element(&os_if->addresses, prefixed_addr, ip, _node);
+  if (!ip) {
+    return;
+  }
+
+  OONF_INFO(LOG_OS_INTERFACE, "Remove address from %s: %s",
+      os_if->name, netaddr_to_string(&nbuf, prefixed_addr));
+
+  avl_remove(&os_if->addresses, &ip->_node);
+  oonf_class_free(&_interface_ip_class, ip);
+}
+
+/**
+ * Parse an incoming IP address information from netlink
+ * @param ifname name of interface
+ * @param msg netlink message
+ */
+static void
+_address_parse_nlmsg(const char *ifname, struct nlmsghdr *msg) {
+  struct ifaddrmsg *ifa_msg;
+  struct rtattr *ifa_attr;
+  int ifa_len;
+  struct os_interface *ifdata;
+  struct netaddr addr;
+  bool update;
+
+  ifa_msg = NLMSG_DATA(msg);
+  ifa_attr = IFA_RTA(ifa_msg);
+  ifa_len = RTM_PAYLOAD(msg);
+
+  ifdata = avl_find_element(&_interface_data_tree, ifname, ifdata, _node);
+  if (!ifdata) {
+    return;
+  }
+
+  OONF_DEBUG(LOG_OS_INTERFACE, "Parse IFA_GETADDR %s (%u) (len=%u)",
+      ifname, ifa_msg->ifa_index, ifa_len);
+
+  update = false;
+  for(; RTA_OK(ifa_attr, ifa_len); ifa_attr = RTA_NEXT(ifa_attr,ifa_len)) {
+    switch(ifa_attr->rta_type) {
+      case IFA_ADDRESS:
+        netaddr_from_binary_prefix(&addr, RTA_DATA(ifa_attr), RTA_PAYLOAD(ifa_attr), 0,
+            ifa_msg->ifa_prefixlen);
+        if (msg->nlmsg_type == RTM_NEWADDR) {
+          _add_address(ifdata, &addr);
+        }
+        else {
+          _remove_address(ifdata, &addr);
+        }
+        update = true;
+        break;
+      default:
+        OONF_DEBUG(LOG_OS_INTERFACE, "ifa_attr_type: %u", ifa_attr->rta_type);
+        break;
+    }
+  }
+
+  if (update) {
+    _update_address_shortcuts(ifdata);
+  }
+
+  _trigger_if_change_including_any(ifdata);
+}
+
 /**
  * Handle incoming rtnetlink multicast messages for interface listeners
  * @param hdr pointer to netlink message
@@ -767,36 +1095,42 @@ static void
 _cb_rtnetlink_message(struct nlmsghdr *hdr) {
   struct ifinfomsg *ifi;
   struct ifaddrmsg *ifa;
-
-  struct os_interface_if_listener *listener;
+  char ifname[IF_NAMESIZE];
 
   if (hdr->nlmsg_type == RTM_NEWLINK || hdr->nlmsg_type == RTM_DELLINK) {
     ifi = (struct ifinfomsg *) NLMSG_DATA(hdr);
-
-    OONF_DEBUG(LOG_OS_INTERFACE, "Linkstatus of interface %d changed", ifi->ifi_index);
-    list_for_each_element(&_ifchange_listener, listener, _node) {
-      listener->if_changed(ifi->ifi_index, (ifi->ifi_flags & IFF_UP) == 0);
+    if (!if_indextoname(ifi->ifi_index, ifname)) {
+      return;
     }
+
+    OONF_DEBUG(LOG_OS_INTERFACE, "Linkstatus of interface (%s) %d changed",
+        ifname, ifi->ifi_index);
+    _link_parse_nlmsg(ifname, hdr);
   }
 
   else if (hdr->nlmsg_type == RTM_NEWADDR || hdr->nlmsg_type == RTM_DELADDR) {
     ifa = (struct ifaddrmsg *) NLMSG_DATA(hdr);
-
-    OONF_DEBUG(LOG_OS_INTERFACE, "Address of interface %u changed", ifa->ifa_index);
-    list_for_each_element(&_ifchange_listener, listener, _node) {
-      listener->if_changed(ifa->ifa_index, (ifa->ifa_flags & IFF_UP) == 0);
+    if (!if_indextoname(ifa->ifa_index, ifname)) {
+      return;
     }
+
+    OONF_DEBUG(LOG_OS_INTERFACE, "Address of interface %s (%u) changed",
+        ifname, ifa->ifa_index);
+    _address_parse_nlmsg(ifname, hdr);
+  }
+  else {
+    OONF_DEBUG(LOG_OS_INTERFACE, "Message type: %u", hdr->nlmsg_type);
   }
 }
 
 /**
  * Handle feedback from netlink socket
- * @param seq
- * @param error
+ * @param seq sequence number of netlink message
+ * @param error error code
  */
 static void
 _cb_rtnetlink_error(uint32_t seq, int error) {
-  struct os_interface_address *addr;
+  struct os_interface_ip_change *addr;
 
   OONF_INFO(LOG_OS_INTERFACE, "Netlink socket provided feedback: %d %d", seq, error);
 
@@ -814,7 +1148,7 @@ _cb_rtnetlink_error(uint32_t seq, int error) {
  */
 static void
 _cb_rtnetlink_timeout(void) {
-  struct os_interface_address *addr;
+  struct os_interface_ip_change *addr;
 
   OONF_INFO(LOG_OS_INTERFACE, "Netlink socket timed out");
 
@@ -825,11 +1159,11 @@ _cb_rtnetlink_timeout(void) {
 
 /**
  * Handle done from multipart netlink messages
- * @param seq
+ * @param seq sequence number of netlink message
  */
 static void
 _cb_rtnetlink_done(uint32_t seq) {
-  struct os_interface_address *addr;
+  struct os_interface_ip_change *addr;
 
   OONF_INFO(LOG_OS_INTERFACE, "Netlink operation finished: %u", seq);
 
@@ -848,7 +1182,7 @@ _cb_rtnetlink_done(uint32_t seq) {
  * @param error error code, 0 if no error
  */
 static void
-_address_finished(struct os_interface_address *addr, int error) {
+_address_finished(struct os_interface_ip_change *addr, int error) {
   if (list_is_node_added(&addr->_internal._node)) {
     /* remove first to prevent any kind of recursive cleanup */
     list_remove(&addr->_internal._node);
@@ -858,3 +1192,121 @@ _address_finished(struct os_interface_address *addr, int error) {
     }
   }
 }
+
+/**
+ * Handle switching between netlink query for links and addresses
+ */
+static void
+_process_end_of_query(void) {
+  if (_link_query_in_progress) {
+    _link_query_in_progress = false;
+
+    if (_trigger_address_query) {
+      _query_interface_addresses();
+    }
+    else if (_trigger_link_query) {
+      _query_interface_links();
+    }
+  }
+  else {
+    _address_query_in_progress = false;
+
+    if (_trigger_link_query) {
+      _query_interface_links();
+    }
+    else if (_trigger_address_query) {
+      _query_interface_addresses();
+    }
+  }
+}
+
+/**
+ * Handle a netlink query that did not work out
+ */
+static void
+_process_bad_end_of_query(void) {
+  /* reactivate query that has failed */
+  if (_link_query_in_progress) {
+    _trigger_link_query = true;
+  }
+  if (_address_query_in_progress) {
+    _trigger_address_query = true;
+  }
+  _process_end_of_query();
+}
+
+/**
+ * Handle an incoming netlink query error
+ * @param seq sequence number of netlink message
+ * @param error error code
+ */
+static void
+_cb_query_error(uint32_t seq __attribute((unused)),
+    int error __attribute((unused))) {
+  _process_bad_end_of_query();
+}
+
+/**
+ * Handle a successful netlink query
+ * @param seq sequence number of netlink message
+ */
+static void
+_cb_query_done(uint32_t seq __attribute((unused))) {
+  _process_end_of_query();
+}
+
+/**
+ * Handle a timeout of a netlink query
+ */
+static void
+_cb_query_timeout(void) {
+  _process_bad_end_of_query();
+}
+
+/**
+ * Handle timer that announces interface state/address changes
+ * @param timer timer instance
+ */
+static void
+_cb_interface_changed(struct oonf_timer_instance *timer) {
+  struct os_interface *data;
+  struct os_interface_listener *interf;
+  bool error;
+
+  data = container_of(timer, struct os_interface, _change_timer);
+
+  OONF_INFO(LOG_OS_INTERFACE, "Interface %s (%u) changed",
+      data->name, data->index);
+
+  error = false;
+  list_for_each_element(&data->_listeners, interf, _node) {
+    if (!interf->_dirty) {
+      continue;
+    }
+
+    if (interf->if_changed && interf->if_changed(interf)) {
+      /* interface change handler had a problem and wants to re-trigger */
+      error = true;
+    }
+    else {
+      /* everything fine, job done */
+      interf->_dirty = false;
+    }
+  }
+
+  if (error) {
+    /* re-trigger */
+    oonf_timer_start(timer, 200);
+  }
+}
+
+/**
+ * Transform remaining parameters into interface sections
+ * @param arg command line parameter
+ * @return always 0 (ok)
+ */
+static int
+_handle_unused_parameter(const char *arg) {
+  cfg_db_add_namedsection(oonf_cfg_get_rawdb(), CFG_INTERFACE_SECTION, arg);
+  return 0;
+}
index d30abb4..9d5db8a 100644 (file)
 
 #include "common/common_types.h"
 #include "subsystems/os_interface.h"
+#include "subsystems/os_generic/os_interface_generic.h"
 
-/**
- * define scope of address on interface
- */
-enum os_addr_scope {
-  /* linklocal scope */
-  OS_ADDR_SCOPE_LINK = RT_SCOPE_LINK,
-  /*! global scope */
-  OS_ADDR_SCOPE_GLOBAL = RT_SCOPE_UNIVERSE,
+enum {
+  /*! interval until an interface change trigger will be activated again */
+  OS_INTERFACE_CHANGE_TRIGGER_INTERVAL = 200,
 };
 
-/**
- * linux specifc data for changing an interface address
- */
-struct os_interface_address_internal {
-  /*! hook into list of IP address change handlers */
-  struct list_entity _node;
+#define OS_INTERFACE_ANY "any"
 
-  /*! netlink sequence number of command sent to the kernel */
-  uint32_t nl_seq;
-};
+EXPORT struct os_interface *os_interface_linux_add(struct os_interface_listener *);
+EXPORT void os_interface_linux_remove(struct os_interface_listener *);
+EXPORT struct avl_tree *os_interface_linux_get_tree(void);
 
-EXPORT void os_interface_linux_listener_add(struct os_interface_if_listener *);
-EXPORT void os_interface_linux_listener_remove(struct os_interface_if_listener *);
-EXPORT int os_interface_linux_state_set(const char *dev, bool up);
-EXPORT int os_interface_linux_address_set(struct os_interface_address *addr);
-EXPORT void os_interface_linux_address_interrupt(struct os_interface_address *addr);
-EXPORT int os_interface_linux_mac_set_by_name(const char *, struct netaddr *mac);
+EXPORT void os_interface_linux_trigger_handler(struct os_interface_listener *);
 
-EXPORT int os_interface_linux_update(struct os_interface_data *, const char *);
-EXPORT int os_interface_linux_init_mesh(struct os_interface *);
-EXPORT void os_interface_linux_cleanup_mesh(struct os_interface *);
+EXPORT int os_interface_linux_state_set(struct os_interface *, bool up);
+EXPORT int os_interface_linux_mac_set(struct os_interface *interf, struct netaddr *mac);
+
+EXPORT int os_interface_linux_address_set(struct os_interface_ip_change *addr);
+EXPORT void os_interface_linux_address_interrupt(struct os_interface_ip_change *addr);
 
 /**
- * Add an interface event listener to the operation system
- * @param listener interface listener
+ * Add an interface to the OONF handling
+ * @param interf network interface
+ * @return interface data object
+ */
+static INLINE struct os_interface *
+os_interface_add(struct os_interface_listener *interf) {
+  return os_interface_linux_add(interf);
+}
+
+/**
+ * Remove an interface from the OONF handling
+ * @param interf network interface
  */
 static INLINE void
-os_interface_listener_add(struct os_interface_if_listener *l) {
-  os_interface_linux_listener_add(l);
+os_interface_remove(struct os_interface_listener *interf) {
+  os_interface_linux_remove(interf);
+}
+
+/**
+ * @return tree of network interfaces
+ */
+static INLINE struct avl_tree *
+os_interface_get_tree(void) {
+  return os_interface_linux_get_tree();
 }
 
 /**
- * Remove an interface event listener to the operation system
- * @param listener interface listener
+ * Trigger an interface change handler
+ * @param interf network interface
  */
 static INLINE void
-os_interface_listener_remove(struct os_interface_if_listener *l) {
-  os_interface_linux_listener_remove(l);
+os_interface_trigger_handler(struct os_interface_listener *interf) {
+  os_interface_linux_trigger_handler(interf);
 }
 
 /**
  * Set interface up or down
- * @param dev pointer to name of interface
+ * @param os_if network interface
  * @param up true if interface should be up, false if down
  * @return -1 if an error happened, 0 otherwise
  */
 static INLINE int
-os_interface_state_set(const char *dev, bool up) {
-  return os_interface_linux_state_set(dev, up);
+os_interface_state_set(struct os_interface *os_if, bool up) {
+  return os_interface_linux_state_set(os_if, up);
 }
 
 /**
@@ -120,7 +126,7 @@ os_interface_state_set(const char *dev, bool up) {
  *   0 otherwise
  */
 static INLINE int
-os_interface_address_set(struct os_interface_address *addr) {
+os_interface_address_set(struct os_interface_ip_change *addr) {
   return os_interface_linux_address_set(addr);
 }
 
@@ -129,61 +135,41 @@ os_interface_address_set(struct os_interface_address *addr) {
  * @param addr interface address change request
  */
 static INLINE void
-os_interface_address_interrupt(struct os_interface_address *addr) {
+os_interface_address_interrupt(struct os_interface_ip_change *addr) {
   os_interface_linux_address_interrupt(addr);
 }
 
 /**
- * Set the mac address of an interface
- * @param name name of interface
- * @param mac mac address
+ * Set mac address of interface
+ * @param os_if interface data object
+ * @param mac new mac address
  * @return -1 if an error happened, 0 otherwise
  */
 static INLINE int
-os_interface_mac_set_by_name(const char *ifname, struct netaddr *mac) {
-  return os_interface_linux_mac_set_by_name(ifname, mac);
+os_interface_mac_set(struct os_interface *os_if, struct netaddr *mac) {
+  return os_interface_linux_mac_set(os_if, mac);
 }
 
-/**
- * Updates the data of an interface.
- * The interface data object will be completely overwritten
- * @param ifdata pointer to an interface data object
- * @param name name of interface
- * @return -1 if an error happened, 0 otherwise
- */
-static INLINE int
-os_interface_update(struct os_interface_data *ifdata, const char *name) {
-  return os_interface_linux_update(ifdata, name);
+static INLINE struct os_interface *
+os_interface_get_data_by_ifindex(unsigned ifindex) {
+  return os_interface_generic_get_data_by_ifindex(ifindex);
 }
 
-/**
- * Initialize interface for mesh usage
- * @param interf pointer to interface object
- * @return -1 if an error happened, 0 otherwise
- */
-static INLINE int
-os_interface_init_mesh(struct os_interface *interf) {
-  return os_interface_linux_init_mesh(interf);
+static INLINE struct os_interface *
+os_interface_get_data_by_ifbaseindex(unsigned ifindex) {
+  return os_interface_generic_get_data_by_ifbaseindex(ifindex);
 }
 
-/**
- * Cleanup interface after mesh usage
- * @param interf pointer to interface object
- */
-static INLINE void
-os_interface_cleanup_mesh(struct os_interface *interf) {
-  os_interface_linux_cleanup_mesh(interf);
+static INLINE const struct netaddr *
+os_interface_get_bindaddress(int af_type,
+    struct netaddr_acl *filter, struct os_interface *ifdata) {
+  return os_interface_generic_get_bindaddress(af_type, filter, ifdata);
 }
 
-/**
- * Set mac address of interface
- * @param ifdata interface data object
- * @param mac new mac address
- * @return -1 if an error happened, 0 otherwise
- */
-static INLINE int
-os_interface_mac_set(struct os_interface_data *ifdata, struct netaddr *mac) {
-  return os_interface_linux_mac_set_by_name(ifdata->name, mac);
+static INLINE  const struct netaddr *
+os_interface_get_prefix_from_dst(
+    struct netaddr *destination, struct os_interface *ifdata) {
+  return os_interface_generic_get_prefix_from_dst(destination, ifdata);
 }
 
 #endif /* OS_INTERFACE_LINUX_H_ */
  * @file
  */
 
-#ifndef OS_INTERFACE_DATA_H_
-#define OS_INTERFACE_DATA_H_
+#ifndef OS_INTERFACE_LINUX_INTERNAL_H_
+#define OS_INTERFACE_LINUX_INTERNAL_H_
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
 
 #include "common/common_types.h"
-#include "common/netaddr.h"
+#include "subsystems/os_interface.h"
 
 /**
- * Representation of interface knowledge of the operation system
+ * define scope of address on interface
  */
-struct os_interface_data {
-  /*! IPv4 Interface addresses with mesh-wide scope (at least) */
-  const struct netaddr *if_v4;
-
-  /*! IPv6 Interface addresses with mesh-wide scope (at least) */
-  const struct netaddr *if_v6;
-
-  /*! IPv6 Interface address with linklocal scope */
-  const struct netaddr *linklocal_v6_ptr;
-
-  /*! mac address of interface */
-  struct netaddr mac;
-
-  /*! list of all addresses of the interface */
-  struct netaddr *addresses;
-
-  /*! number of addresses of the interface */
-  size_t addrcount;
-
-  /*! list of all prefixes of the interface */
-  struct netaddr *prefixes;
-
-  /*! number of prefixes of the interface */
-  size_t prefixcount;
+enum os_addr_scope {
+  /* linklocal scope */
+  OS_ADDR_SCOPE_LINK = RT_SCOPE_LINK,
+  /*! global scope */
+  OS_ADDR_SCOPE_GLOBAL = RT_SCOPE_UNIVERSE,
+};
 
-  /*! interface name */
-  char name[IF_NAMESIZE];
+/**
+ * linux specifc data for changing an interface address
+ */
+struct os_interface_address_change_internal {
+  /*! hook into list of IP address change handlers */
+  struct list_entity _node;
 
-  /*! interface index */
-  unsigned index;
+  /*! netlink sequence number of command sent to the kernel */
+  uint32_t nl_seq;
+};
 
+struct os_interface_internal {
   /**
-   * interface index of base interface (for vlan),
-   * same for normal interface
+   * usage counter to keep track of the number of users on
+   * this interface who want to send mesh traffic
    */
-  unsigned base_index;
+  uint32_t mesh_counter;
 
-  /*! true if the interface exists and is up */
-  bool up;
-
-  /*! true if this is a loopback interface */
-  bool loopback;
+  /**
+   * used to store internal state of interfaces before
+   * configuring them for manet data forwarding.
+   * Only used by os_specific code.
+   */
+  uint32_t _original_state;
 };
 
-#endif /* OS_INTERFACE_DATA_H_ */
+#endif /* OS_INTERFACE_LINUX_INTERNAL_H_ */
index 10d631e..4e2b2a8 100644 (file)
@@ -390,7 +390,7 @@ int
 os_system_linux_netlink_send(struct os_system_netlink *nl,
     struct nlmsghdr *nl_hdr) {
   _seq_used = (_seq_used + 1) & INT32_MAX;
-  OONF_INFO(nl->used_by->logging, "Prepare to send netlink '%s' message %u (%u bytes)",
+  OONF_DEBUG(nl->used_by->logging, "Prepare to send netlink '%s' message %u (%u bytes)",
       nl->name, _seq_used, nl_hdr->nlmsg_len);
 
   nl_hdr->nlmsg_seq = _seq_used;
@@ -560,7 +560,7 @@ _flush_netlink_buffer(struct os_system_netlink *nl) {
   else {
     nl->msg_in_transit += buffer->messages;
 
-    OONF_INFO(nl->used_by->logging,
+    OONF_DEBUG(nl->used_by->logging,
         "netlink %s: Sent %u bytes (%u messages in transit)",
         nl->name, buffer->total, nl->msg_in_transit);
 
@@ -670,7 +670,7 @@ netlink_rcv_retry:
     goto netlink_rcv_retry;
   }
 
-  OONF_INFO(nl->used_by->logging, "Got netlink '%s' message of %"
+  OONF_DEBUG(nl->used_by->logging, "Got netlink '%s' message of %"
       PRINTF_SSIZE_T_SPECIFIER" bytes", nl->name, ret);
   OONF_DEBUG_HEX(nl->used_by->logging, nl->in, ret,
       "Content of netlink '%s' message:", nl->name);
@@ -680,7 +680,7 @@ netlink_rcv_retry:
   /* loop through netlink headers */
   len = (size_t) ret;
   for (nh = nl->in; NLMSG_OK (nh, len); nh = NLMSG_NEXT (nh, len)) {
-    OONF_INFO(nl->used_by->logging,
+    OONF_DEBUG(nl->used_by->logging,
         "Netlink '%s' message received: type %d seq %u\n",
         nl->name, nh->nlmsg_type, nh->nlmsg_seq);
 
@@ -743,7 +743,7 @@ _handle_nl_err(struct os_system_netlink *nl, struct nlmsghdr *nh) {
 
   err = (struct nlmsgerr *) NLMSG_DATA(nh);
 
-  OONF_INFO(nl->used_by->logging,
+  OONF_DEBUG(nl->used_by->logging,
       "Received netlink '%s' seq %u feedback (%u bytes): %s (%d)",
       nl->name, nh->nlmsg_seq, nh->nlmsg_len, strerror(-err->error), -err->error);
 
index ccf236d..90bb4e0 100644 (file)
@@ -102,6 +102,7 @@ _cleanup(void) {
 
 /**
  * Open a new virtual interface
+ * @param sock os socket
  * @param vif pointer to virtual interface object
  * @return -1 if an error happened, 0 otherwise
  */
index e0200f6..5f2f224 100644 (file)
@@ -52,7 +52,7 @@
 #include "common/common_types.h"
 #include "common/list.h"
 #include "common/netaddr.h"
-#include "subsystems/oonf_interface.h"
+#include "subsystems/os_interface.h"
 #include "core/oonf_logging.h"
 #include "subsystems/os_system.h"
 
index 5ee66d0..dd2c999 100644 (file)
@@ -29,7 +29,6 @@ set (OONF_APP_DEFAULT_CFG_HANDLER Compact)
 IF (NOT OONF_STATIC_PLUGINS)
     set (OONF_STATIC_PLUGINS class
                              clock
-                             interface
                              layer2
                              packet_socket
                              socket
index 0cbc43e..4e12394 100644 (file)
@@ -29,7 +29,6 @@ set (OONF_APP_DEFAULT_CFG_HANDLER Compact)
 IF (NOT OONF_STATIC_PLUGINS)
     set (OONF_STATIC_PLUGINS class
                              clock
-                             interface
                              layer2
                              packet_socket
                              socket
index 2663a5b..e4958c0 100644 (file)
@@ -30,7 +30,6 @@ IF (NOT OONF_STATIC_PLUGINS)
     set (OONF_STATIC_PLUGINS class
                              clock
                              duplicate_set
-                             interface
                              layer2
                              packet_socket
                              rfc5444
index da94d85..0de3b9c 100644 (file)
@@ -30,7 +30,6 @@ IF (NOT OONF_STATIC_PLUGINS)
     set (OONF_STATIC_PLUGINS class
                              clock
                              duplicate_set
-                             interface
                              layer2
                              packet_socket
                              rfc5444