Merge branch 'master' into mpr_rework
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Fri, 22 Jul 2016 10:58:07 +0000 (12:58 +0200)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Fri, 22 Jul 2016 10:58:07 +0000 (12:58 +0200)
186 files changed:
.gitignore
CMakeLists.txt
cmake/cc_flags.cmake
cmake/generate_archive.cmake
cmake/lib_config.cmake
cmake/link_app.cmake
files/create_debian_package.sh [new file with mode: 0755]
openwrt/oonf-dlep-proxy-git-debug/Makefile [new file with mode: 0644]
openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.hotplug [new file with mode: 0755]
openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.init [new file with mode: 0755]
openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.uci [new file with mode: 0644]
openwrt/oonf-dlep-proxy-git/Makefile
openwrt/oonf-dlep-radio-git-debug/Makefile [new file with mode: 0644]
openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.hotplug [new file with mode: 0755]
openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.init [new file with mode: 0755]
openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.uci [new file with mode: 0644]
openwrt/oonf-dlep-radio-git/Makefile
openwrt/oonf-init-scripts/Makefile
openwrt/oonf-olsrd2-git-debug/Makefile [new file with mode: 0644]
openwrt/oonf-olsrd2-git-debug/files/olsrd2.hotplug [new file with mode: 0755]
openwrt/oonf-olsrd2-git-debug/files/olsrd2.init [new file with mode: 0755]
openwrt/oonf-olsrd2-git-debug/files/olsrd2.uci [new file with mode: 0644]
openwrt/oonf-olsrd2-git/Makefile
src-api/common/avl.c
src-api/common/avl.h
src-api/common/isonumber.c
src-api/common/list.h
src-api/common/netaddr.c
src-api/common/netaddr.h
src-api/common/netaddr_acl.c
src-api/config/cfg.c
src-api/config/cfg.h
src-api/config/cfg_db.c
src-api/config/cfg_schema.c
src-api/config/cfg_schema.h
src-api/core/CMakeLists.txt
src-api/core/oonf_main.c
src-api/core/os_core.h
src-api/core/os_generic/os_core_generic_syslog.c [moved from src-api/core/os_generic/os_core_generic.c with 91% similarity]
src-api/core/os_generic/os_core_generic_syslog.h [moved from src-api/core/os_generic/os_core_generic.h with 79% similarity]
src-api/core/os_linux/os_core_linux.c [moved from src-api/core/os_linux/os_core_linux_get_random.c with 82% similarity]
src-api/core/os_linux/os_core_linux.h [new file with mode: 0644]
src-plugins/CMakeLists.txt
src-plugins/crypto/simple_security/simple_security.c
src-plugins/generic/CMakeLists.txt
src-plugins/generic/cfg_uciloader/cfg_uciloader.c
src-plugins/generic/dlep/dlep_extension.c
src-plugins/generic/dlep/dlep_interface.c
src-plugins/generic/dlep/dlep_interface.h
src-plugins/generic/dlep/dlep_session.c
src-plugins/generic/dlep/dlep_session.h
src-plugins/generic/dlep/dlep_writer.c
src-plugins/generic/dlep/ext_base_metric/metric.c
src-plugins/generic/dlep/ext_base_proto/proto.c
src-plugins/generic/dlep/ext_base_proto/proto_radio.c
src-plugins/generic/dlep/ext_base_proto/proto_router.c
src-plugins/generic/dlep/radio/dlep_radio.c
src-plugins/generic/dlep/radio/dlep_radio_interface.c
src-plugins/generic/dlep/router/dlep_router.c
src-plugins/generic/dlep/router/dlep_router_interface.c
src-plugins/generic/dlep/router/dlep_router_interface.h
src-plugins/generic/dlep/router/dlep_router_session.c
src-plugins/generic/eth_listener/eth_listener.c
src-plugins/generic/example/example.c
src-plugins/generic/layer2_config/CMakeLists.txt [new file with mode: 0644]
src-plugins/generic/layer2_config/layer2_config.c [new file with mode: 0644]
src-plugins/generic/layer2_config/layer2_config.h [moved from src-api/core/os_linux/os_core_linux_locking_file.c with 75% similarity]
src-plugins/generic/layer2_generator/layer2_generator.c
src-plugins/generic/layer2info/layer2info.c
src-plugins/generic/link_config/link_config.c
src-plugins/generic/link_config/link_config.h
src-plugins/generic/nl80211_listener/nl80211_get_interface.c
src-plugins/generic/nl80211_listener/nl80211_get_mpp.c
src-plugins/generic/nl80211_listener/nl80211_get_station_dump.c
src-plugins/generic/nl80211_listener/nl80211_get_survey.c
src-plugins/generic/nl80211_listener/nl80211_get_wiphy.c
src-plugins/generic/nl80211_listener/nl80211_listener.c
src-plugins/generic/nl80211_listener/nl80211_listener.h
src-plugins/generic/remotecontrol/remotecontrol.c
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/ff_dat_metric/ff_dat_metric.h
src-plugins/nhdp/hysteresis_olsrv1/hysteresis_olsrv1.c
src-plugins/nhdp/mpr/mpr.c
src-plugins/nhdp/neighbor_probing/neighbor_probing.c
src-plugins/nhdp/nhdp/nhdp.c
src-plugins/nhdp/nhdp/nhdp_db.c
src-plugins/nhdp/nhdp/nhdp_domain.c
src-plugins/nhdp/nhdp/nhdp_domain.h
src-plugins/nhdp/nhdp/nhdp_interfaces.c
src-plugins/nhdp/nhdp/nhdp_interfaces.h
src-plugins/nhdp/nhdp/nhdp_reader.c
src-plugins/nhdp/nhdp/nhdp_writer.c
src-plugins/nhdp/nhdpcheck/nhdpcheck.c
src-plugins/nhdp/nhdpinfo/nhdpinfo.c
src-plugins/olsrv2/lan_import/lan_import.c
src-plugins/olsrv2/netjsoninfo/netjsoninfo.c
src-plugins/olsrv2/olsrv2/olsrv2.c
src-plugins/olsrv2/olsrv2/olsrv2.h
src-plugins/olsrv2/olsrv2/olsrv2_lan.c
src-plugins/olsrv2/olsrv2/olsrv2_originator.c
src-plugins/olsrv2/olsrv2/olsrv2_reader.c
src-plugins/olsrv2/olsrv2/olsrv2_routing.c
src-plugins/olsrv2/olsrv2/olsrv2_tc.c
src-plugins/olsrv2/olsrv2/olsrv2_writer.c
src-plugins/olsrv2/olsrv2info/olsrv2info.c
src-plugins/subsystems/CMakeLists.txt
src-plugins/subsystems/oonf_duplicate_set.c
src-plugins/subsystems/oonf_http.c
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_socket.c
src-plugins/subsystems/oonf_socket.h
src-plugins/subsystems/oonf_stream_socket.c
src-plugins/subsystems/oonf_stream_socket.h
src-plugins/subsystems/oonf_telnet.c
src-plugins/subsystems/oonf_telnet.h
src-plugins/subsystems/oonf_timer.c
src-plugins/subsystems/oonf_timer.h
src-plugins/subsystems/os_clock.h
src-plugins/subsystems/os_fd.h [moved from src-plugins/subsystems/os_socket.h with 90% similarity]
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_fd_generic_set_dscp.c
src-plugins/subsystems/os_generic/os_fd_generic_set_dscp.h
src-plugins/subsystems/os_generic/os_fd_generic_set_nonblocking.c
src-plugins/subsystems/os_generic/os_fd_generic_set_nonblocking.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_init_half_route_key.c
src-plugins/subsystems/os_generic/os_routing_generic_init_half_route_key.h [new file with mode: 0644]
src-plugins/subsystems/os_generic/os_routing_generic_rt_to_string.c
src-plugins/subsystems/os_generic/os_routing_generic_rt_to_string.h [new file with mode: 0644]
src-plugins/subsystems/os_generic/os_routing_generic_rtkey_avlcomp.c
src-plugins/subsystems/os_interface.h
src-plugins/subsystems/os_linux/os_clock_linux.c
src-plugins/subsystems/os_linux/os_clock_linux.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 58% similarity]
src-plugins/subsystems/os_linux/os_routing_linux.c
src-plugins/subsystems/os_linux/os_routing_linux.h
src-plugins/subsystems/os_linux/os_system_linux.c
src-plugins/subsystems/os_linux/os_system_linux.h
src-plugins/subsystems/os_linux/os_tunnel_linux.c
src-plugins/subsystems/os_linux/os_tunnel_linux.h
src-plugins/subsystems/os_linux/os_vif_linux.c
src-plugins/subsystems/os_linux/os_vif_linux.h
src-plugins/subsystems/os_routing.h
src-plugins/subsystems/os_system.h
src-plugins/subsystems/os_tunnel.h
src-plugins/subsystems/os_vif.h
src/CMakeLists.txt
src/dlep-radio/CMakeLists.txt
src/dlep-router/CMakeLists.txt
src/olsrd2-dlep/CMakeLists.txt [new file with mode: 0644]
src/olsrd2/CMakeLists.txt
src/olsrd2/debian/changelog [new file with mode: 0644]
src/olsrd2/debian/compat [new file with mode: 0644]
src/olsrd2/debian/control [new file with mode: 0644]
src/olsrd2/debian/docs/olsrd2_static.1 [new file with mode: 0644]
src/olsrd2/debian/olsrd2.conf [new file with mode: 0644]
src/olsrd2/debian/olsrd2.dirs [new file with mode: 0644]
src/olsrd2/debian/olsrd2.init [new file with mode: 0644]
src/olsrd2/debian/olsrd2.manpages [new file with mode: 0644]
src/olsrd2/debian/olsrd2.service [new file with mode: 0644]
src/olsrd2/debian/rules [new file with mode: 0644]
src/olsrd2/debian/source/format [new file with mode: 0644]
src/oonf/OONF_APP_README
tests/common/test_common_avl.c
tests/common/test_common_isonumber.c

index a7afb14..3e57424 100644 (file)
@@ -1,13 +1,13 @@
 /.cproject
 /.project
 /.settings
-/html
 /cmake/version.cmake
 /.kdev4/
 /*.kdev4
 /*.tar.gz
 /*.tar.bz2
 /*.zip
+/*.deb
 /doxygen_sqlite3.db
 /doxygen_objdb_*.tmp
 /doxygen_entrydb_*.tmp
index b94c410..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 ####
 ###########################
@@ -44,6 +56,8 @@ ADD_CUSTOM_TARGET(targz  COMMAND ${CMAKE_COMMAND}
                                  -D BINARY:STRING=${PROJECT_BINARY_DIR}
                                  -D VERSION:STRING=${VERSION}
                                  -D FORMAT:STRING=tar.gz
+                                 -D TARBALL:STRING=${TARBALL}
+                                 -D TARPREFIX:STRING=${TARPREFIX}
                                  -P ${CMAKE_SOURCE_DIR}/cmake/generate_archive.cmake)
                                 
 ADD_CUSTOM_TARGET(tarbz2 COMMAND ${CMAKE_COMMAND}
@@ -51,12 +65,16 @@ ADD_CUSTOM_TARGET(tarbz2 COMMAND ${CMAKE_COMMAND}
                                  -D BINARY:STRING=${PROJECT_BINARY_DIR}
                                  -D VERSION:STRING=${VERSION}
                                  -D FORMAT:STRING=tar.bz2
+                                 -D TARBALL:STRING=${TARBALL}
+                                 -D TARPREFIX:STRING=${TARPREFIX}
                                  -P ${CMAKE_SOURCE_DIR}/cmake/generate_archive.cmake)
 ADD_CUSTOM_TARGET(zip    COMMAND ${CMAKE_COMMAND}
                                  -D SOURCE:STRING=${CMAKE_SOURCE_DIR}
                                  -D BINARY:STRING=${PROJECT_BINARY_DIR}
                                  -D VERSION:STRING=${VERSION}
                                  -D FORMAT:STRING=zip
+                                 -D TARBALL:STRING=${TARBALL}
+                                 -D TARPREFIX:STRING=${TARPREFIX}
                                  -P ${CMAKE_SOURCE_DIR}/cmake/generate_archive.cmake)
 
 #########################
index db5142b..adc5d98 100644 (file)
@@ -148,6 +148,7 @@ add_compiler_flag(-Wsync-nand)
 add_compiler_flag(-Wundef)
 add_compiler_flag(-Wunused-parameter)
 add_compiler_flag(-Wjump-misses-init)
+add_compiler_flag(-Wlogical-op)
 
 # check for link time optimization
 # check_c_compiler_flag("-flto" test_lto)
index 980a6fc..857dd72 100644 (file)
@@ -23,9 +23,19 @@ FILE (COPY ${BINARY}/${VERSIONFILE} DESTINATION ${SOURCE})
 execute_process(COMMAND git add ${SOURCE}/${VERSIONFILE} WORKING_DIRECTORY ${SOURCE})
 execute_process(COMMAND git stash create OUTPUT_VARIABLE COMMIT WORKING_DIRECTORY ${SOURCE} OUTPUT_STRIP_TRAILING_WHITESPACE)
 
+IF (NOT TARBALL)
+    SET(TARBALL "${SOURCE}/oonf_${VERSION}.${FORMAT}")
+ENDIF (NOT TARBALL)
+
+IF (NOT TARPREFIX)
+    SET (TARPREFIX "oonf_${VERSION}")
+ENDIF (NOT TARPREFIX)
+
 # generate archive
-execute_process(COMMAND git archive --prefix=oonf_${VERSION}/ -o ${SOURCE}/oonf_${VERSION}.${FORMAT} ${COMMIT} WORKING_DIRECTORY ${SOURCE})
+execute_process(COMMAND git archive --prefix=${TARPREFIX}/ -o ${TARBALL} ${COMMIT} WORKING_DIRECTORY ${SOURCE})
 
 # remove version file
 FILE (REMOVE ${SOURCE}/${VERSIONFILE})
 execute_process(COMMAND git rm --quiet ${SOURCE}/${VERSIONFILE} WORKING_DIRECTORY ${SOURCE})
+
+message ("created ${TARBALL}")
index fce1cc4..8cd74fd 100644 (file)
@@ -17,7 +17,8 @@ set (CMAKE_BUILD_TYPE Debug CACHE STRING
 # maximum logging level
 set (OONF_LOGGING_LEVEL debug CACHE STRING 
      "Maximum logging level compiled into OONF API (warn, info, debug)")
-
+SET_PROPERTY(CACHE OONF_LOGGING_LEVEL PROPERTY STRINGS debug info warn)
 # remove help texts from application, core-api and plugins
 set (OONF_REMOVE_HELPTEXT false CACHE BOOL
      "Set if you want to remove the help texts from application to reduce size")
index 32196b4..1009850 100644 (file)
@@ -24,6 +24,12 @@ function (oonf_create_app executable static_plugins optional_static_plugins)
         message (STATUS "Static plugins for ${executable} app:")
     ENDIF(VERBOSE)
 
+    IF(OONF_NEED_ROOT)
+        SET(DESTINATION sbin)
+    ELSE(OONF_NEED_ROOT)
+        SET(DESTINATION bin)
+    ENDIF(OONF_NEED_ROOT)
+
     # standard static linked targets
     SET(OBJECT_TARGETS )
     SET(EXTERNAL_LIBRARIES )
@@ -33,11 +39,15 @@ function (oonf_create_app executable static_plugins optional_static_plugins)
     configure_file(${CMAKE_SOURCE_DIR}/src/app_data.c.in ${PROJECT_BINARY_DIR}/${executable}_app_data.c)
 
     FOREACH(plugin ${optional_static_plugins})
-        IF(TARGET oonf_static_${plugin})
-            list (APPEND static_plugins ${plugin})
-        ELSE(TARGET oonf_static_${plugin})
-            message (STATUS "    Optional plugin ${plugin} is not available for executable ${executable}")
-        ENDIF(TARGET oonf_static_${plugin})
+        list(FIND static_plugins ${plugin} insanity)
+
+        IF(${insanity} EQUAL -1)
+            IF(TARGET oonf_static_${plugin})
+                list (APPEND static_plugins ${plugin})
+            ELSE(TARGET oonf_static_${plugin})
+                message (STATUS "    Optional plugin ${plugin} is not available for executable ${executable}")
+            ENDIF(TARGET oonf_static_${plugin})
+        ENDIF(${insanity} EQUAL -1)
     ENDFOREACH(plugin)
 
     # run through list of static plugins
@@ -97,10 +107,10 @@ function (oonf_create_app executable static_plugins optional_static_plugins)
     
     # create install targets
     INSTALL (TARGETS ${executable}_dynamic RUNTIME 
-                                           DESTINATION bin 
+                                           DESTINATION ${DESTINATION}
                                            COMPONENT component_${executable}_dynamic)
     INSTALL (TARGETS ${executable}_static  RUNTIME
-                                           DESTINATION bin 
+                                           DESTINATION ${DESTINATION}
                                            COMPONENT component_${executable}_static)
 
     # add custom install targets
diff --git a/files/create_debian_package.sh b/files/create_debian_package.sh
new file mode 100755 (executable)
index 0000000..30d40db
--- /dev/null
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+# store source directory
+SOURCE=$(git rev-parse --show-toplevel)
+
+# handle script input and variables
+: ${BUILD:=oonf_build_debian}
+
+BUILDDIR=/tmp/${BUILD}
+
+if [ "$#" -eq "0" ]
+then
+        TARGET=olsrd2
+else
+        TARGET=${1}
+fi
+
+if [ "${TOOLCHAIN}" != "" ]
+then
+    echo "Using toolchain file: ${TOOLCHAIN}"
+    TOOLCHAIN="-D CMAKE_TOOLCHAIN_FILE=`realpath ${TOOLCHAIN}`"
+fi
+
+if [ "${ARCH}" != "" ]
+then
+    echo "Using architecture: ${ARCH}"
+    ARCH="-a${ARCH}"
+fi
+
+# calculate version and tarball names
+VERSION=`git describe --abbrev=0| sed -e "s/^v//"`
+FULLVERSION=`git describe`
+VERSIONCOUNT=`git rev-list v${VERSION}..HEAD --count`
+
+TARPREFIX=${TARGET}_${VERSION}
+TARBALL=${BUILDDIR}/${TARPREFIX}.orig.tar.gz
+
+# check if target is there and prepared for a debian package
+if [ ! -d ${SOURCE}/src/${TARGET} ]
+then
+    echo "Could not find target '${TARGET}'"
+    exit 1
+fi
+
+if [ ! -f ${SOURCE}/src/${TARGET}/debian/changelog ]
+then
+    echo "Could not find target '${TARGET}' debian changelog"
+    exit 1
+fi
+
+if [ ! -f ${SOURCE}/src/${TARGET}/debian/control ]
+then
+    echo "Could not find target '${TARGET}' debian control file"
+    exit 1
+fi
+
+# create clean build directory
+if [ -d ${BUILDDIR} ]
+then
+    echo "remove ${BUILDDIR}"
+    rm -r ${BUILDDIR}
+fi
+
+mkdir -p ${BUILDDIR}
+cd ${BUILDDIR}
+
+# create directory structure
+mkdir build
+
+# build tarball of current source
+cd build
+
+cmake -DTARBALL=${TARBALL} -DTARPREFIX=${TARPREFIX} ${SOURCE}
+make targz
+
+cd ${BUILDDIR}
+
+# uncompress tarball
+tar xf ${TARBALL}
+
+# build debian directory from template
+cd ${TARPREFIX}
+
+cp -r ${SOURCE}/src/${TARGET}/debian ./
+cp ${SOURCE}/files/default_licence.txt ./debian/copyright
+
+# adapt changelog template
+sed -i -e "s@SHORTVERSION@${VERSION}-${VERSIONCOUNT}@" \
+       -e "s@FULLVERSION@${FULLVERSION}@" \
+       -e "s@DATETIME@`date -R`@" \
+       ./debian/changelog
+
+# adapt rules template
+sed -i -e "s@SOURCETOOLCHAIN@${TOOLCHAIN}@" ./debian/rules
+
+# create debian package
+debuild -us -uc ${ARCH}
+
+# copy package to source directory
+cp ${BUILDDIR}/*.deb ${SOURCE}
diff --git a/openwrt/oonf-dlep-proxy-git-debug/Makefile b/openwrt/oonf-dlep-proxy-git-debug/Makefile
new file mode 100644 (file)
index 0000000..bdb6986
--- /dev/null
@@ -0,0 +1,59 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=oonf-dlep-proxy-git-debug
+PKG_VERSION:=2016-05-31
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_SOURCE_DIR=$(CURDIR)/../../
+CMAKE_OPTIONS=-D OONF_NO_WERROR:Bool=true \
+              -D OONF_LOGGING_LEVEL:String=debug \
+              -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;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 \
+              -D CMAKE_PREFIX_PATH=$(STAGING_DIR)/usr \
+              -D CMAKE_BUILD_TYPE:String=Debug
+
+define Package/oonf-git/template
+       SECTION:=net
+       CATEGORY:=Network
+       MAINTAINER:=Henning Rogge <hrogge@gmail.com>
+       SUBMENU:=OLSR.org network framework
+       URL:=http://www.olsr.org/
+endef
+
+define Package/oonf-dlep-proxy-git-debug
+       $(call Package/oonf-git/template) 
+       TITLE:= Build DLEP Radio+Router Agent
+       DEPENDS:=+librt +libnl-tiny +libuci +oonf-init-scripts
+       VERSION:=$(PKG_VERSION)
+endef
+
+Build/Compile=$(call Build/Compile/Default,dlep_radio_static)
+Build/Install=
+
+define Build/Install
+       $(INSTALL_BIN) -D $(PKG_BUILD_DIR)/$(MAKE_PATH)/dlep_radio_static $(PKG_INSTALL_DIR)/usr/sbin/dlep_proxy;
+endef
+
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include -I${STAGING_DIR}/usr/include/libnl-tiny
+
+define Package/oonf-dlep-proxy-git-debug/install
+       $(INSTALL_BIN)  -D $(PKG_BUILD_DIR)/dlep_radio_static $(1)/usr/sbin/dlep_proxy
+       $(INSTALL_BIN)  -D ./files/dlep_proxy.init            $(1)/etc/init.d/dlep_proxy
+       $(INSTALL_BIN)  -D ./files/dlep_proxy.hotplug         $(1)/etc/hotplug.d/iface/50-dlep_proxy
+       $(INSTALL_DATA) -D ./files/dlep_proxy.uci             $(1)/etc/config/dlep_proxy
+endef
+
+define Package/oonf-dlep-proxy-git-debug/conffiles
+/etc/config/dlep_proxy
+endef
+
+$(eval $(call BuildPackage,oonf-dlep-proxy-git-debug))
diff --git a/openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.hotplug b/openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.hotplug
new file mode 100755 (executable)
index 0000000..3ebe1b7
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+DAEMON='dlep_proxy'
+
+. /lib/functions/oonf_hotplug.sh
diff --git a/openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.init b/openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.init
new file mode 100755 (executable)
index 0000000..c47ff84
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh /etc/rc.common
+
+START=82
+DAEMON='dlep_proxy'
+
+. /lib/functions/oonf_init.sh
diff --git a/openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.uci b/openwrt/oonf-dlep-proxy-git-debug/files/dlep_proxy.uci
new file mode 100644 (file)
index 0000000..72a4d7d
--- /dev/null
@@ -0,0 +1,24 @@
+config global
+       option 'failfast'       'no'
+       option 'pidfile'        '/var/run/dlep_proxy.pid'
+       option 'lockfile'       '/var/lock/dlep_proxy'
+
+config log
+       option 'syslog'         'true'
+       option 'stderr'         'true'
+#      option 'file'           '/var/log/dlep_proxy.log'
+#      option 'info'           'all'
+#      option 'debug'          'all'
+
+config telnet
+#      option 'port' '2009'
+
+#config dlep_radio
+#  list 'name' 'eth0'
+#  option 'datapath_if' 'eth1'
+#  option 'not_proxied' 'false'
+#  option 'proxied' 'true'
+
+#config dlep-router
+#  list 'name' 'eth0'
+#  option 'datapath_if' 'eth0'
index 624694c..1cf4de7 100644 (file)
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=oonf-dlep-proxy-git
-PKG_VERSION:=2015-10-08
+PKG_VERSION:=2016-05-31
 
 CMAKE_INSTALL:=1
 
@@ -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_socket;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 \
diff --git a/openwrt/oonf-dlep-radio-git-debug/Makefile b/openwrt/oonf-dlep-radio-git-debug/Makefile
new file mode 100644 (file)
index 0000000..3790fb3
--- /dev/null
@@ -0,0 +1,59 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=oonf-dlep-radio-git-debug
+PKG_VERSION:=2016-05-31
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_SOURCE_DIR=$(CURDIR)/../../
+CMAKE_OPTIONS=-D OONF_NO_WERROR:Bool=true \
+              -D OONF_LOGGING_LEVEL:String=debug \
+              -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;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 \
+              -D CMAKE_PREFIX_PATH=$(STAGING_DIR)/usr \
+              -D CMAKE_BUILD_TYPE:String=Debug
+
+define Package/oonf-git/template
+       SECTION:=net
+       CATEGORY:=Network
+       MAINTAINER:=Henning Rogge <hrogge@gmail.com>
+       SUBMENU:=OLSR.org network framework
+       URL:=http://www.olsr.org/
+endef
+
+define Package/oonf-dlep-radio-git-debug
+       $(call Package/oonf-git/template) 
+       TITLE:= Build DLEP Radio Agent (Debug)
+       DEPENDS:=+librt +libnl-tiny +libuci +oonf-init-scripts
+       VERSION:=$(PKG_VERSION)
+endef
+
+Build/Compile=$(call Build/Compile/Default,dlep_radio_static)
+Build/Install=
+
+define Build/Install
+       $(INSTALL_BIN) -D $(PKG_BUILD_DIR)/$(MAKE_PATH)/dlep_radio_static $(PKG_INSTALL_DIR)/usr/sbin/dlep_radio;
+endef
+
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include -I${STAGING_DIR}/usr/include/libnl-tiny
+
+define Package/oonf-dlep-radio-git-debug/install
+       $(INSTALL_BIN)  -D $(PKG_BUILD_DIR)/dlep_radio_static $(1)/usr/sbin/dlep_radio
+       $(INSTALL_BIN)  -D ./files/dlep_radio.init            $(1)/etc/init.d/dlep_radio
+       $(INSTALL_BIN)  -D ./files/dlep_radio.hotplug         $(1)/etc/hotplug.d/iface/50-dlep_radio
+       $(INSTALL_DATA) -D ./files/dlep_radio.uci             $(1)/etc/config/dlep_radio
+endef
+
+define Package/oonf-dlep-radio-git-debug/conffiles
+/etc/config/dlep_radio
+endef
+
+$(eval $(call BuildPackage,oonf-dlep-radio-git-debug))
diff --git a/openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.hotplug b/openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.hotplug
new file mode 100755 (executable)
index 0000000..b7146a4
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+DAEMON='dlep_radio'
+
+. /lib/functions/oonf_hotplug.sh
diff --git a/openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.init b/openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.init
new file mode 100755 (executable)
index 0000000..c660a21
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh /etc/rc.common
+
+START=82
+DAEMON='dlep_radio'
+
+. /lib/functions/oonf_init.sh
diff --git a/openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.uci b/openwrt/oonf-dlep-radio-git-debug/files/dlep_radio.uci
new file mode 100644 (file)
index 0000000..2f1ac9b
--- /dev/null
@@ -0,0 +1,24 @@
+config global
+       option 'failfast' 'no'
+       option 'pidfile'  '/var/run/dlep_radio.pid'
+       option 'lockfile' '/var/lock/dlep_radio'
+
+config log
+       option 'syslog'   'true'
+       option 'stderr'   'true'
+#      option 'file'             '/var/log/dlep_radio.log'
+#      option 'info'     'all'
+#      option 'debug'    'all'
+
+config telnet
+#      option 'port' '2009'
+
+config dlep_radio
+  list   'name'        'wlan0'
+  option 'datapath_if' 'br-lan'
+  option 'not_proxied' 'false'
+  option 'proxied'     'true'
+
+config nl80211_listener
+  option 'if'          'wlan0'
+  option 'interval'    '1.0'
index 9cfbddd..ff03ddd 100644 (file)
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=oonf-dlep-radio-git
-PKG_VERSION:=2015-10-08
+PKG_VERSION:=2016-05-31
 
 CMAKE_INSTALL:=1
 
@@ -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_socket;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 d3fb79a..7c6c5aa 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=oonf-init-scripts
-PKG_VERSION:=2015-06-08
+PKG_VERSION:=2016-05-31
 PKG_RELEASE:=1
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
 
diff --git a/openwrt/oonf-olsrd2-git-debug/Makefile b/openwrt/oonf-olsrd2-git-debug/Makefile
new file mode 100644 (file)
index 0000000..7140674
--- /dev/null
@@ -0,0 +1,59 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=oonf-olsrd2-git-debug
+PKG_VERSION:=2016-05-31
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_SOURCE_DIR=$(CURDIR)/../../
+CMAKE_OPTIONS=-D OONF_NO_WERROR:Bool=true \
+              -D OONF_LOGGING_LEVEL:String=debug \
+              -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;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;lan_import;auto_ll4" \
+              -D INSTALL_LIB_DIR:Path=lib/oonf \
+              -D INSTALL_INCLUDE_DIR:Path=include/oonf \
+              -D INSTALL_CMAKE_DIR:Path=lib/oonf \
+              -D CMAKE_PREFIX_PATH=$(STAGING_DIR)/usr \
+              -D CMAKE_BUILD_TYPE:String=Debug
+
+define Package/oonf-git/template
+       SECTION:=net
+       CATEGORY:=Network
+       MAINTAINER:=Henning Rogge <hrogge@gmail.com>
+       SUBMENU:=OLSR.org network framework
+       URL:=http://www.olsr.org/
+endef
+
+define Package/oonf-olsrd2-git-debug
+       $(call Package/oonf-git/template) 
+       TITLE:= Build Olsrd V2 Routing Agent
+       DEPENDS:=+librt +libnl-tiny +libuci +oonf-init-scripts
+       VERSION:=$(PKG_VERSION)
+endef
+
+Build/Compile=$(call Build/Compile/Default,olsrd2_static)
+Build/Install=
+
+define Build/Install
+       $(INSTALL_BIN) -D $(PKG_BUILD_DIR)/$(MAKE_PATH)/olsrd2_static $(PKG_INSTALL_DIR)/usr/sbin/olsrd2;
+endef
+
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include -I${STAGING_DIR}/usr/include/libnl-tiny
+
+define Package/oonf-olsrd2-git-debug/install
+       $(INSTALL_BIN)  -D $(PKG_BUILD_DIR)/olsrd2_static $(1)/usr/sbin/olsrd2
+       $(INSTALL_BIN)  -D ./files/olsrd2.init            $(1)/etc/init.d/olsrd2
+       $(INSTALL_BIN)  -D ./files/olsrd2.hotplug         $(1)/etc/hotplug.d/iface/50-olsrd2
+       $(INSTALL_DATA) -D ./files/olsrd2.uci             $(1)/etc/config/olsrd2
+endef
+
+define Package/oonf-olsrd2-git-debug/conffiles
+/etc/config/olsrd2
+endef
+
+$(eval $(call BuildPackage,oonf-olsrd2-git-debug))
diff --git a/openwrt/oonf-olsrd2-git-debug/files/olsrd2.hotplug b/openwrt/oonf-olsrd2-git-debug/files/olsrd2.hotplug
new file mode 100755 (executable)
index 0000000..3a277ce
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+DAEMON='olsrd2'
+
+. /lib/functions/oonf_hotplug.sh
diff --git a/openwrt/oonf-olsrd2-git-debug/files/olsrd2.init b/openwrt/oonf-olsrd2-git-debug/files/olsrd2.init
new file mode 100755 (executable)
index 0000000..debae98
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh /etc/rc.common
+
+START=82
+DAEMON='olsrd2'
+
+. /lib/functions/oonf_init.sh
diff --git a/openwrt/oonf-olsrd2-git-debug/files/olsrd2.uci b/openwrt/oonf-olsrd2-git-debug/files/olsrd2.uci
new file mode 100644 (file)
index 0000000..9df4c7e
--- /dev/null
@@ -0,0 +1,40 @@
+config global
+       option 'failfast'       'no'
+       option 'pidfile'        '/var/run/olsrd2.pid'
+       option 'lockfile'       '/var/lock/olsrd2'
+
+config log
+       option 'syslog'         'true'
+       option 'stderr'         'true'
+#      option 'file'           '/var/log/olsrd2.log'
+#      option 'info'           'all'
+#      option 'debug'          'all'
+
+config telnet
+#      option 'port' '2009'
+
+config olsrv2
+# list 'lan' '::/0'
+# list 'lan' '0.0.0.0/0'
+
+config interface
+       option 'ifname' 'loopback'
+
+config interface
+       list 'ifname' 'WIFI'
+       list 'ifname' 'wlanadhoc'
+       list 'ifname' 'wlanadhocRADIO1'
+
+config interface
+       list 'ifname' 'wan'
+       option 'ignore' '1'
+#      option 'rx_bitrate' '100M'
+#      option 'tx_bitrate' '100M'
+#      option 'signal' '-20'
+
+config interface
+       list 'ifname' 'lan'
+       option 'ignore' '1'
+#      option 'rx_bitrate' '1G'
+#      option 'tx_bitrate' '1G'
+#      option 'signal' '-10'
index ed4ebd5..51ba933 100644 (file)
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=oonf-olsrd2-git
-PKG_VERSION:=2015-10-08
+PKG_VERSION:=2016-05-31
 
 CMAKE_INSTALL:=1
 
@@ -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_socket;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" \
+              -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;lan_import;auto_ll4" \
               -D INSTALL_LIB_DIR:Path=lib/oonf \
               -D INSTALL_INCLUDE_DIR:Path=include/oonf \
               -D INSTALL_CMAKE_DIR:Path=lib/oonf \
index 52ae993..ca6b548 100644 (file)
@@ -64,6 +64,8 @@ static void _avl_rotate_right(struct avl_tree *tree, struct avl_node *node);
 static void _avl_rotate_left(struct avl_tree *tree, struct avl_node *node);
 static void _avl_post_remove(struct avl_tree *tree, struct avl_node *node);
 static struct avl_node *_avl_local_min(struct avl_node *node);
+static struct avl_node *_avl_find_last(struct avl_tree *tree, struct avl_node *
+node);
 
 /**
  * Initialize a new avl_tree struct
@@ -189,6 +191,27 @@ avl_find_greaterequal(const struct avl_tree *tree, const void *key) {
   return node;
 }
 
+/**
+ * Finds the end of linked list from the avl node
+ * @param tree pointer to tree
+ * @param node pointer
+ * @return pointer to last node of the list
+ */
+struct avl_node*
+_avl_find_last(struct avl_tree *tree, struct avl_node* last)
+{
+  struct avl_node *next;
+  while (!list_is_last(&tree->list_head, &last->list)) {
+    next = list_next_element(last, list);
+    if (!next->follower) {
+      break;
+    }
+    last = next;
+  }
+  return last;
+}
+
+
 /**
  * Inserts an avl_node into a tree
  * @param tree pointer to tree
@@ -199,7 +222,7 @@ avl_find_greaterequal(const struct avl_tree *tree, const void *key) {
 int
 avl_insert(struct avl_tree *tree, struct avl_node *new)
 {
-  struct avl_node *node, *next, *last;
+  struct avl_node *node, *last;
   int diff;
 
   new->parent = NULL;
@@ -219,16 +242,6 @@ avl_insert(struct avl_tree *tree, struct avl_node *new)
 
   node = _avl_find_rec(tree->root, new->key, tree->comp, &diff);
 
-  last = node;
-
-  while (!list_is_last(&tree->list_head, &last->list)) {
-    next = list_next_element(last, list);
-    if (!next->follower) {
-      break;
-    }
-    last = next;
-  }
-
   diff = (*tree->comp) (new->key, node->key);
 
   if (diff == 0) {
@@ -238,7 +251,7 @@ avl_insert(struct avl_tree *tree, struct avl_node *new)
     new->follower = true;
 
     /* add new node outside the tree, because key is already present */
-    _avl_insert_after(tree, last, new);
+    _avl_insert_after(tree, node, new);
     return 0;
   }
 
@@ -252,6 +265,7 @@ avl_insert(struct avl_tree *tree, struct avl_node *new)
   }
 
   if (node->balance == -1) {
+    last = _avl_find_last(tree, node);
     _avl_insert_after(tree, last, new);
 
     node->balance = 0;
@@ -267,6 +281,7 @@ avl_insert(struct avl_tree *tree, struct avl_node *new)
     _post_insert(tree, node);
   }
   else { /* diff > 0 */
+    last = _avl_find_last(tree, node);
     _avl_insert_after(tree, last, new);
 
     node->balance = 1;
index d8901ab..ab99f5b 100644 (file)
@@ -148,7 +148,7 @@ EXPORT void avl_remove(struct avl_tree *, struct avl_node *);
  * @return true if node is the first one of the tree, false otherwise
  */
 static INLINE bool
-avl_is_first(struct avl_tree *tree, struct avl_node *node) {
+avl_is_first(const struct avl_tree *tree, const struct avl_node *node) {
   return tree->list_head.next == &node->list;
 }
 
@@ -158,7 +158,7 @@ avl_is_first(struct avl_tree *tree, struct avl_node *node) {
  * @return true if node is the last one of the tree, false otherwise
  */
 static INLINE bool
-avl_is_last(struct avl_tree *tree, struct avl_node *node) {
+avl_is_last(const struct avl_tree *tree, const struct avl_node *node) {
   return tree->list_head.prev == &node->list;
 }
 
@@ -167,7 +167,7 @@ avl_is_last(struct avl_tree *tree, struct avl_node *node) {
  * @return true if the tree is empty, false otherwise
  */
 static INLINE bool
-avl_is_empty(struct avl_tree *tree) {
+avl_is_empty(const struct avl_tree *tree) {
   return tree->count == 0;
 }
 
@@ -176,7 +176,7 @@ avl_is_empty(struct avl_tree *tree) {
  * @return true if node is currently in a tree, false otherwise
  */
 static INLINE bool
-avl_is_node_added(struct avl_node *node) {
+avl_is_node_added(const struct avl_node *node) {
   return list_is_node_added(&node->list);
 }
 
index 7ef69cf..e14fa2d 100644 (file)
@@ -182,6 +182,9 @@ isonumber_to_u64(uint64_t *dst, const char *iso, int fraction, bool binary) {
   }
 
   if (*next == 0) {
+    for (frac = 0; frac < fraction; frac++) {
+      num *= 10;
+    }
     *dst = num;
     return 0;
   }
@@ -310,9 +313,8 @@ _isonumber_u64_to_string(char *out, size_t out_len,
   out[len++] = '.';
   n = number;
 
-  if (*unit_modifier != ' ') {
-    fraction = 3;
-  }
+  /* show three fractional digits */
+  fraction = 3;
 
   while (true) {
     n = n % multiplier;
@@ -334,8 +336,7 @@ _isonumber_u64_to_string(char *out, size_t out_len,
     }
   }
 
-  if (!raw) {
-    out[idx++] = ' ';
+  if (!raw && *unit_modifier != ' ') {
     out[idx++] = *unit_modifier;
   }
   out[idx++] = 0;
index a84cc44..3c62ce0 100644 (file)
@@ -164,7 +164,7 @@ list_remove(struct list_entity *entity) {
  * @return true if list is empty, false otherwise
  */
 static INLINE bool
-list_is_empty(struct list_entity *head) {
+list_is_empty(const struct list_entity *head) {
   return head->next == head && head->prev == head;
 }
 
@@ -175,7 +175,7 @@ list_is_empty(struct list_entity *head) {
  *   false otherwise
  */
 static INLINE bool
-list_is_node_added(struct list_entity *node) {
+list_is_node_added(const struct list_entity *node) {
   return node->next != NULL && node->prev != NULL;
 }
 
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 474da79..fc2bde3 100644 (file)
@@ -70,6 +70,9 @@ netaddr_acl_remove(struct netaddr_acl *acl) {
   free(acl->reject);
 
   memset(acl, 0, sizeof(*acl));
+
+  assert(acl->accept == NULL);
+  assert(acl->reject == NULL);
 }
 
 /**
@@ -87,8 +90,8 @@ netaddr_acl_from_strarray(struct netaddr_acl *acl,
   accept_count = 0;
   reject_count = 0;
 
-  /* clear acl struct */
-  memset(acl, 0, sizeof(*acl));
+  /* clear acl struct and free existing data */
+  netaddr_acl_remove(acl);
 
   /* count number of address entries */
   strarray_for_each_element(value, ptr) {
index 8dabebb..98d22e5 100644 (file)
 #include "config/cfg.h"
 
 static int avl_comp_cfgio(const void *txt1, const void *txt2);
+
+/* phy interface conversion function pointer */
+static int (*_get_phy_if)(char *phy_ifname, const char *ifname) = NULL;
+
 /**
  * Initialize a configuration instance
  * @param instance pointer to cfg_instance
@@ -175,6 +179,36 @@ cfg_get_choice_index(const char *key, const char **array, size_t array_size) {
   return -1;
 }
 
+/**
+ * Set a handler to transform a logical interface name into a physical one
+ * @param get_phy_if function pointer to transformer function, NULL to reset
+ */
+void
+cfg_set_ifname_handler(int (*get_phy_if)(char *phy_ifname, const char *ifname)) {
+  _get_phy_if = get_phy_if;
+}
+
+/**
+ * Get a physical interface name from a logical one. If no handler
+ * is available it will fall back to the identity function
+ * (phyiscal = logical name)
+ * @param phy_if target buffer for physical interface name,
+ *    must be IF_NAMESIZE sized
+ * @param ifname logical interface name
+ * @return physical interface name (will never be NULL)
+ */
+const char *
+cfg_get_phy_if(char *phy_if, const char *ifname) {
+  if (_get_phy_if && !_get_phy_if(phy_if, ifname)) {
+    return phy_if;
+  }
+
+  if (phy_if != ifname) {
+    strscpy(phy_if, ifname, IF_NAMESIZE);
+  }
+  return phy_if;
+}
+
 /**
  * AVL tree comparator for case insensitive strings.
  * Custom pointer is the length of the memory to compare.
index 298cd7f..ebd8e7b 100644 (file)
@@ -82,6 +82,9 @@ EXPORT int cfg_get_choice_index(const char *value, const char **array, size_t ar
 
 EXPORT int cfg_avlcmp_keys(const void *p1, const void *p2);
 
+EXPORT void cfg_set_ifname_handler(int (*get_phy_if)(char *phy_ifname, const char *ifname));
+EXPORT const char *cfg_get_phy_if(char *phy_if, const char *ifname);
+
 /**
  * Compares to keys/names of two section types/names or entry names.
  * A NULL pointer is considered larger than any valid string.
index 1e47a12..6f9a5eb 100644 (file)
@@ -417,12 +417,13 @@ cfg_db_get_entry_value(struct cfg_db *db, const char *section_type,
 const struct const_strarray *
 cfg_db_get_schema_entry_value(const struct cfg_named_section *section,
     const struct cfg_schema_entry *schema_entry) {
-  struct cfg_entry *entry;
+  const struct const_strarray *value;
 
   if (section) {
-    entry = cfg_db_get_entry(section, schema_entry->key.entry);
-    if (entry) {
-      return (struct const_strarray *)&entry->val;
+    value = cfg_db_get_entry_value(section->section_type->db,
+        section->section_type->type, section->name, schema_entry->key.entry);
+    if (value) {
+      return value;
     }
   }
 
index 8c1ed22..f8feb0b 100644 (file)
@@ -681,6 +681,10 @@ cfg_schema_tobin_strptr(const struct cfg_schema_entry *s_entry __attribute__((un
     const struct const_strarray *value, void *reference) {
   char **ptr;
 
+  if (s_entry->bin_size != sizeof(*ptr)) {
+    return -1;
+  }
+
   ptr = (char **)reference;
   if (*ptr) {
     free(*ptr);
@@ -703,6 +707,10 @@ cfg_schema_tobin_strarray(const struct cfg_schema_entry *s_entry,
     const struct const_strarray *value, void *reference) {
   char *ptr;
 
+  if (s_entry->bin_size < s_entry->validate_param[0].s) {
+    return -1;
+  }
+
   ptr = (char *)reference;
 
   strscpy(ptr, strarray_get_first_c(value), s_entry->validate_param[0].s);
@@ -723,6 +731,10 @@ cfg_schema_tobin_choice(const struct cfg_schema_entry *s_entry,
     const struct const_strarray *value, void *reference) {
   int *ptr;
 
+  if (s_entry->bin_size != sizeof(int)) {
+    return -1;
+  }
+
   ptr = (int *)reference;
 
   *ptr = cfg_get_choice_index(strarray_get_first_c(value),
@@ -744,10 +756,14 @@ cfg_schema_tobin_int(const struct cfg_schema_entry *s_entry,
   int64_t i;
   int result;
 
+  if (s_entry->bin_size != s_entry->validate_param[2].u16[0]) {
+    return -1;
+  }
+
   result = isonumber_to_s64(&i, strarray_get_first_c(value),
-      s_entry->validate_param[2].i16[1], s_entry->validate_param[2].i16[2] == 2);
+      s_entry->validate_param[2].u16[1], s_entry->validate_param[2].u16[2] == 2);
   if (result == 0) {
-    switch (s_entry->validate_param[2].i16[0]) {
+    switch (s_entry->validate_param[2].u16[0]) {
       case 4:
         *((int32_t *)reference) = i;
         break;
@@ -773,6 +789,10 @@ cfg_schema_tobin_netaddr(const struct cfg_schema_entry *s_entry __attribute__((u
     const struct const_strarray *value, void *reference) {
   struct netaddr *ptr;
 
+  if (s_entry->bin_size != sizeof(*ptr)) {
+    return -1;
+  }
+
   ptr = (struct netaddr *)reference;
 
   return netaddr_from_string(ptr, strarray_get_first_c(value));
@@ -791,6 +811,10 @@ cfg_schema_tobin_acl(const struct cfg_schema_entry *s_entry __attribute__((unuse
      const struct const_strarray *value, void *reference) {
   struct netaddr_acl *ptr;
 
+  if (s_entry->bin_size != sizeof(*ptr)) {
+    return -1;
+  }
+
   ptr = (struct netaddr_acl *)reference;
   netaddr_acl_remove(ptr);
 
@@ -812,6 +836,10 @@ cfg_schema_tobin_bitmap256(const struct cfg_schema_entry *s_entry __attribute__(
   const char *ptr;
   int idx;
 
+  if (s_entry->bin_size != sizeof(*bitmap)) {
+    return -1;
+  }
+
   bitmap = (struct bitmap256 *)reference;
   memset(bitmap, 0, sizeof(*bitmap));
 
@@ -852,6 +880,10 @@ cfg_schema_tobin_bool(const struct cfg_schema_entry *s_entry __attribute__((unus
     const struct const_strarray *value, void *reference) {
   bool *ptr;
 
+  if (s_entry->bin_size != sizeof(*ptr)) {
+    return -1;
+  }
+
   ptr = (bool *)reference;
 
   *ptr = cfg_get_bool(strarray_get_first_c(value));
@@ -871,6 +903,10 @@ cfg_schema_tobin_stringlist(const struct cfg_schema_entry *s_entry __attribute__
     const struct const_strarray *value, void *reference) {
   struct strarray *array;
 
+  if (s_entry->bin_size != sizeof(*array)) {
+    return -1;
+  }
+
   array = (struct strarray *)reference;
 
   if (!value->value[0]) {
index 78ef8a6..19cf9a0 100644 (file)
@@ -113,7 +113,7 @@ struct cfg_schema_entry;
  * @param max maximum allowed parameter value
  * @param args variable list of additional arguments
  */
-#define _CFG_VALIDATE_INT(p_name, p_def, p_help, size, fraction, base2, min, max, args...)   _CFG_VALIDATE(p_name, p_def, p_help, .cb_validate = cfg_schema_validate_int, .cb_valhelp = cfg_schema_help_int, .validate_param = {{.i64 = (min)}, {.i64 = (max)}, {.i16 = {size, fraction, !!(base2) ? 2 : 10}}}, ##args )
+#define _CFG_VALIDATE_INT(p_name, p_def, p_help, size, fraction, base2, min, max, args...)   _CFG_VALIDATE(p_name, p_def, p_help, .cb_validate = cfg_schema_validate_int, .cb_valhelp = cfg_schema_help_int, .validate_param = {{.i64 = (min)}, {.i64 = (max)}, {.u16 = {size, fraction, !!(base2) ? 2 : 10}}}, ##args )
 
 /**
  * Creates a cfg_schema_entry for a parameter that does not need to be validated
@@ -411,6 +411,13 @@ struct cfg_schema_entry;
  * };
  */
 
+/**
+ * Helper macro that calculates the size in bytes of a struct field
+ * @param p_reference reference to instance of struct
+ * @param p_field name of field in the struct for the parameter,
+ */
+#define calculate_size(p_reference, p_field)   sizeof(((struct p_reference *)0)->p_field)
+
 /**
  * Helper macro to create a cfg_schema_entry for an integer parameter
  * that can be mapped into a binary struct.
@@ -427,7 +434,7 @@ struct cfg_schema_entry;
  * @param max maximum allowed parameter value
  * @param args variable list of additional arguments
  */
-#define _CFG_MAP_INT(p_reference, p_field, p_name, p_def, p_help, size, fraction, base2, min, max, args...)   _CFG_VALIDATE_INT(p_name, p_def, p_help, size, fraction, base2, min, max, .cb_to_binary = cfg_schema_tobin_int, .bin_offset = offsetof(struct p_reference, p_field), ##args )
+#define _CFG_MAP_INT(p_reference, p_field, p_name, p_def, p_help, size, fraction, base2, min, max, args...)   _CFG_VALIDATE_INT(p_name, p_def, p_help, size, fraction, base2, min, max, .cb_to_binary = cfg_schema_tobin_int, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args )
 
 /**
  * Creates a cfg_schema_entry for a parameter that does not need to be validated
@@ -440,7 +447,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_STRING(p_reference, p_field, p_name, p_def, p_help, args...)                                  _CFG_VALIDATE(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_strptr, .bin_offset = offsetof(struct p_reference, p_field), ##args )
+#define CFG_MAP_STRING(p_reference, p_field, p_name, p_def, p_help, args...)                                  _CFG_VALIDATE(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_strptr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args )
 
 /**
  * Creates a cfg_schema_entry for a string parameter with a maximum length
@@ -454,7 +461,7 @@ struct cfg_schema_entry;
  * @param maxlen maximum number of characters in string
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_STRING_LEN(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                      CFG_VALIDATE_STRING_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strptr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_STRING_LEN(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                      CFG_VALIDATE_STRING_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strptr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a string parameter with a maximum length
@@ -468,7 +475,7 @@ struct cfg_schema_entry;
  * @param maxlen maximum number of characters in string
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_STRING_ARRAY(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                    CFG_VALIDATE_STRING_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strarray, .bin_offset = offsetof(struct p_reference, p_field), ##args )
+#define CFG_MAP_STRING_ARRAY(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                    CFG_VALIDATE_STRING_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strarray, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args )
 
 /**
  * Creates a cfg_schema_entry for a string parameter with
@@ -481,7 +488,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_PRINTABLE(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_PRINTABLE(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_strptr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_PRINTABLE(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_PRINTABLE(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_strptr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a string parameter with a maximum length,
@@ -495,7 +502,7 @@ struct cfg_schema_entry;
  * @param maxlen maximum number of characters in string
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_PRINTABLE_LEN(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                   CFG_VALIDATE_PRINTABLE_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strptr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_PRINTABLE_LEN(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                   CFG_VALIDATE_PRINTABLE_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strptr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a string parameter with a maximum length,
@@ -509,7 +516,7 @@ struct cfg_schema_entry;
  * @param maxlen maximum number of characters in string
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_PRINTABLE_ARRAY(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                 CFG_VALIDATE_PRINTABLE_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strarray, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_PRINTABLE_ARRAY(p_reference, p_field, p_name, p_def, p_help, maxlen, args...)                 CFG_VALIDATE_PRINTABLE_LEN(p_name, p_def, p_help, maxlen, .cb_to_binary = cfg_schema_tobin_strarray, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a parameter that can be choosen
@@ -524,7 +531,7 @@ struct cfg_schema_entry;
  *   (not a pointer to the array, ARRAYSIZE() would not work)
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_CHOICE(p_reference, p_field, p_name, p_def, p_help, p_list, args...)                          CFG_VALIDATE_CHOICE(p_name, p_def, p_help, p_list, .cb_to_binary = cfg_schema_tobin_choice, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_CHOICE(p_reference, p_field, p_name, p_def, p_help, p_list, args...)                          CFG_VALIDATE_CHOICE(p_name, p_def, p_help, p_list, .cb_to_binary = cfg_schema_tobin_choice, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a 32 bit signed integer parameter
@@ -603,7 +610,7 @@ struct cfg_schema_entry;
  * @param unspec true if the parameter also allows an unspecified address
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_NETADDR(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)                 CFG_VALIDATE_NETADDR(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_NETADDR(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)                 CFG_VALIDATE_NETADDR(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a layer-2 network address,
@@ -618,7 +625,7 @@ struct cfg_schema_entry;
  * @param unspec true if the parameter also allows an unspecified address
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_NETADDR_HWADDR(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)          CFG_VALIDATE_NETADDR_HWADDR(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_NETADDR_HWADDR(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)          CFG_VALIDATE_NETADDR_HWADDR(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a MAC (ethernet) network address
@@ -633,7 +640,7 @@ struct cfg_schema_entry;
  * @param unspec true if the parameter also allows an unspecified address
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_NETADDR_MAC48(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)           CFG_VALIDATE_NETADDR_MAC48(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_NETADDR_MAC48(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)           CFG_VALIDATE_NETADDR_MAC48(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for an EUI-64 network address
@@ -648,7 +655,7 @@ struct cfg_schema_entry;
  * @param unspec true if the parameter also allows an unspecified address
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_NETADDR_EUI64(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)           CFG_VALIDATE_NETADDR_EUI64(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_NETADDR_EUI64(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)           CFG_VALIDATE_NETADDR_EUI64(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for an IPv4 network address
@@ -663,7 +670,7 @@ struct cfg_schema_entry;
  * @param unspec true if the parameter also allows an unspecified address
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_NETADDR_V4(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)              CFG_VALIDATE_NETADDR_V4(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_NETADDR_V4(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)              CFG_VALIDATE_NETADDR_V4(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for an IPv6 network address
@@ -678,7 +685,7 @@ struct cfg_schema_entry;
  * @param unspec true if the parameter also allows an unspecified address
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_NETADDR_V6(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)              CFG_VALIDATE_NETADDR_V6(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_NETADDR_V6(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)              CFG_VALIDATE_NETADDR_V6(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for an IP network address
@@ -693,7 +700,7 @@ struct cfg_schema_entry;
  * @param unspec true if the parameter also allows an unspecified address
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_NETADDR_V46(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)             CFG_VALIDATE_NETADDR_V46(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_NETADDR_V46(p_reference, p_field, p_name, p_def, p_help, prefix, unspec, args...)             CFG_VALIDATE_NETADDR_V46(p_name, p_def, p_help, prefix, unspec, .cb_to_binary = cfg_schema_tobin_netaddr, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a network address based
@@ -706,7 +713,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_ACL(p_reference, p_field, p_name, p_def, p_help, args...)                                     CFG_VALIDATE_ACL(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_ACL(p_reference, p_field, p_name, p_def, p_help, args...)                                     CFG_VALIDATE_ACL(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a network address based
@@ -720,7 +727,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_ACL_HWADDR(p_reference, p_field, p_name, p_def, p_help, args...)                              CFG_VALIDATE_ACL_HWADDR(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_ACL_HWADDR(p_reference, p_field, p_name, p_def, p_help, args...)                              CFG_VALIDATE_ACL_HWADDR(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a network address based
@@ -734,7 +741,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_ACL_MAC48(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_ACL_MAC48(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_ACL_MAC48(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_ACL_MAC48(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a network address based
@@ -748,7 +755,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_ACL_EUI64(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_ACL_EUI64(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_ACL_EUI64(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_ACL_EUI64(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a network address based
@@ -762,7 +769,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_ACL_V4(p_reference, p_field, p_name, p_def, p_help, args...)                                  CFG_VALIDATE_ACL_V4(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_ACL_V4(p_reference, p_field, p_name, p_def, p_help, args...)                                  CFG_VALIDATE_ACL_V4(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a network address based
@@ -776,7 +783,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_ACL_V6(p_reference, p_field, p_name, p_def, p_help, args...)                                  CFG_VALIDATE_ACL_V6(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_ACL_V6(p_reference, p_field, p_name, p_def, p_help, args...)                                  CFG_VALIDATE_ACL_V6(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a network address based
@@ -790,7 +797,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_ACL_V46(p_reference, p_field, p_name, p_def, p_help, args...)                                 CFG_VALIDATE_ACL_V46(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_ACL_V46(p_reference, p_field, p_name, p_def, p_help, args...)                                 CFG_VALIDATE_ACL_V46(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_acl, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for 256 bit bitmap that can be
@@ -803,7 +810,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_BITMAP256(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_BITMAP256(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_bitmap256, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_BITMAP256(p_reference, p_field, p_name, p_def, p_help, args...)                               CFG_VALIDATE_BITMAP256(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_bitmap256, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for a boolean parameter
@@ -816,7 +823,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_BOOL(p_reference, p_field, p_name, p_def, p_help, args...)                                    CFG_VALIDATE_BOOL(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_bool, .bin_offset = offsetof(struct p_reference, p_field), ##args)
+#define CFG_MAP_BOOL(p_reference, p_field, p_name, p_def, p_help, args...)                                    CFG_VALIDATE_BOOL(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_bool, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), ##args)
 
 /**
  * Creates a cfg_schema_entry for list of strings that can
@@ -829,7 +836,7 @@ struct cfg_schema_entry;
  * @param p_help help text for configuration entry
  * @param args variable list of additional arguments
  */
-#define CFG_MAP_STRINGLIST(p_reference, p_field, p_name, p_def, p_help, args...)                              _CFG_VALIDATE(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_stringlist, .bin_offset = offsetof(struct p_reference, p_field), .list = true, ##args )
+#define CFG_MAP_STRINGLIST(p_reference, p_field, p_name, p_def, p_help, args...)                              _CFG_VALIDATE(p_name, p_def, p_help, .cb_to_binary = cfg_schema_tobin_stringlist, .bin_size = calculate_size(p_reference, p_field), .bin_offset = offsetof(struct p_reference, p_field), .list = true, ##args )
 
 
 /*! convenience definition for configuration that only allows access from loopback */
@@ -1027,6 +1034,9 @@ struct cfg_schema_entry {
   /*! offset of current binary data compared to reference pointer */
   size_t bin_offset;
 
+  /*! size in bytes of the target buffer to allow sanity checks */
+  size_t bin_size;
+
   /*! pointer to value before change (for delta calculation) */
   const struct const_strarray *pre;
 
index 80b30d9..36447bb 100644 (file)
@@ -23,12 +23,12 @@ SET(OONF_CORE_INCLUDES oonf_appdata.h
 # TODO: add BSD and WIN32
 IF(LINUX)
     SET(OONF_CORE_SRCS ${OONF_CORE_SRCS}
-                       os_generic/os_core_generic.c
-                       os_linux/os_core_linux_locking_file.c
-                       os_linux/os_core_linux_get_random.c
+                       os_generic/os_core_generic_syslog.c
+                       os_linux/os_core_linux.c
                        )
     SET(OONF_CORE_INCLUDES ${OONF_CORE_INCLUDES}
-                       os_generic/os_core_generic.h
+                       os_generic/os_core_generic_syslog.h
+                       os_linux/os_core_linux.h
                        )
 ENDIF(LINUX)
 
index 8974f85..d9f22ae 100644 (file)
@@ -161,6 +161,7 @@ static const char *help_text =
 int
 oonf_main(int argc, char **argv, const struct oonf_appdata *appdata) {
   int return_code;
+  int result;
 
   /* early initialization */
   return_code = 1;
@@ -207,8 +208,8 @@ oonf_main(int argc, char **argv, const struct oonf_appdata *appdata) {
   return_code = 1;
 
   /* read global section early */
-  if (oonf_cfg_update_globalcfg(true)) {
-    OONF_WARN(LOG_MAIN, "Cannot read global configuration section");
+  if ((result = oonf_cfg_update_globalcfg(true))) {
+    OONF_WARN(LOG_MAIN, "Cannot read global configuration section (%d)", result);
     goto oonf_cleanup;
   }
 
index b06f00a..62ffdc4 100644 (file)
 #ifndef OS_CORE_H_
 #define OS_CORE_H_
 
+#include <sys/time.h>
+
 #include "common/common_types.h"
 #include "core/oonf_logging.h"
 
-#if defined(__linux__)
-#include "core/os_generic/os_core_generic.h"
-#elif defined (BSD)
-#include "core/os_generic/os_core_generic.h"
-#elif defined (_WIN32)
-#include "core/os_win32/os_core_win32.h"
-#else
-#error "Unknown operation system"
-#endif
-
-
 /* pre-decleare inlines */
 static INLINE int os_core_gettimeofday(struct timeval *tv);
 
-void os_core_init(const char *appname);
-void os_core_cleanup(void);
+static INLINE int os_core_init(const char *appname);
+static INLINE void os_core_cleanup(void);
+
+static INLINE int os_core_syslog(enum oonf_log_severity, const char *);
+static INLINE int os_core_create_lockfile(const char *);
+static INLINE int os_core_get_random(void *dst, size_t length);
 
-EXPORT void os_core_syslog(enum oonf_log_severity, const char *);
-EXPORT int os_core_create_lockfile(const char *);
-EXPORT int os_core_get_random(void *dst, size_t length);
+#if defined(__linux__)
+#include "os_linux/os_core_linux.h"
+#else
+#error "Unknown operation system"
+#endif
 
 #endif /* OS_CORE_H_ */
similarity index 91%
rename from src-api/core/os_generic/os_core_generic.c
rename to src-api/core/os_generic/os_core_generic_syslog.c
index 1b11e6a..4c7d66d 100644 (file)
 #include "core/os_core.h"
 
 /**
- * Initialize core
+ * Initialize syslog
  * @param appname name of the application for syslog
  */
 void
-os_core_init(const char *appname) {
-  /* seed random number generator */
-  srandom(times(NULL) + getpid());
-
-  /* open logfile */
+os_core_generic_syslog_init(const char *appname) {
+  /* open syslog */
   openlog(appname, LOG_PID | LOG_ODELAY, LOG_DAEMON);
   setlogmask(LOG_UPTO(LOG_DEBUG));
 }
 
 /**
- * Cleanup core
+ * Cleanup syslog
  */
 void
-os_core_cleanup(void) {
+os_core_generic_syslog_cleanup(void) {
   closelog();
 }
 
@@ -81,7 +78,7 @@ os_core_cleanup(void) {
  * @param msg line to print
  */
 void
-os_core_syslog(enum oonf_log_severity severity, const char *msg) {
+os_core_generic_syslog(enum oonf_log_severity severity, const char *msg) {
   int log_sev;
 
   switch (severity) {
similarity index 79%
rename from src-api/core/os_generic/os_core_generic.h
rename to src-api/core/os_generic/os_core_generic_syslog.h
index c947d33..ce217b6 100644 (file)
  * @file
  */
 
-#ifndef OS_CORE_GENERIC_H_
-#define OS_CORE_GENERIC_H_
+#ifndef OS_CORE_GENERIC_SYSLOG_H_
+#define OS_CORE_GENERIC_SYSLOG_H_
 
-#include <sys/time.h>
-#include <stdlib.h>
+#include "common/common_types.h"
 
-#include "core/os_core.h"
+void os_core_generic_syslog_init(const char *appname);
+void os_core_generic_syslog_cleanup(void);
 
-/*! default folder for Linux lockfile */
-#define OS_CORE_LOCKFILE_FOLDER        "/var/run/"
+EXPORT void os_core_generic_syslog(
+    enum oonf_log_severity severity, const char *msg);
 
-/**
- * Inline wrapper around gettimeofday
- * @param tv pointer to target timeval object
- * @return -1 if an error happened, 0 otherwise
- */
-static INLINE int
-os_core_gettimeofday(struct timeval *tv) {
-  return gettimeofday(tv, NULL);
-}
-
-#endif /* OS_CORE_GENERIC_H_ */
+#endif /* OS_CORE_GENERIC_SYSLOG_H_ */
similarity index 82%
rename from src-api/core/os_linux/os_core_linux_get_random.c
rename to src-api/core/os_linux/os_core_linux.c
index e89d486..db32024 100644 (file)
@@ -43,6 +43,7 @@
  * @file
  */
 
+#include <sys/file.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -57,7 +58,7 @@
  * @return 0 if the random data was generated, -1 if an error happened
  */
 int
-os_core_get_random(void *dst, size_t length) {
+os_core_linux_get_random(void *dst, size_t length) {
   int random_fd;
   ssize_t result;
   uint8_t *u8ptr;
@@ -83,3 +84,27 @@ os_core_get_random(void *dst, size_t length) {
   close(random_fd);
   return 0;
 }
+
+/**
+ * Create a lock file of a certain name
+ * @param path name of lockfile including path
+ * @return 0 if the lock was created successfully, false otherwise
+ */
+int
+os_core_linux_create_lockfile(const char *path) {
+  int lock_fd;
+
+  /* create file for lock */
+  lock_fd = open(path, O_RDWR | O_CREAT, S_IRWXU);
+  if (lock_fd == -1) {
+    return -1;
+  }
+
+  if (flock(lock_fd, LOCK_EX | LOCK_NB)) {
+    close(lock_fd);
+    return -1;
+  }
+
+  /* lock will be released when process ends */
+  return 0;
+}
diff --git a/src-api/core/os_linux/os_core_linux.h b/src-api/core/os_linux/os_core_linux.h
new file mode 100644 (file)
index 0000000..49e34e4
--- /dev/null
@@ -0,0 +1,116 @@
+
+/*
+ * 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 OS_CORE_LINUX_H_
+#define OS_CORE_LINUX_H_
+
+#include <sys/time.h>
+#include <stdlib.h>
+
+#include "core/os_generic/os_core_generic_syslog.h"
+#include "core/os_core.h"
+
+/*! default folder for Linux lockfile */
+#define OS_CORE_LOCKFILE_FOLDER        "/var/run/"
+
+EXPORT int os_core_linux_get_random(void *dst, size_t length);
+EXPORT int os_core_linux_create_lockfile(const char *path);
+
+/**
+ * Initialize core
+ * @param appname name of the application
+ */
+static INLINE int
+os_core_init(const char *appname) {
+  os_core_generic_syslog_init(appname);
+  return 0;
+}
+
+/**
+ * Cleanup core
+ */
+static INLINE void
+os_core_cleanup(void) {
+  os_core_generic_syslog_cleanup();
+}
+
+static INLINE int
+os_core_syslog(enum oonf_log_severity sev, const char *msg) {
+  os_core_generic_syslog(sev, msg);
+  return 0;
+}
+
+/**
+ * Create a lock file of a certain name
+ * @param path name of lockfile including path
+ * @return 0 if the lock was created successfully, false otherwise
+ */
+static INLINE int
+os_core_create_lockfile(const char *path) {
+  return os_core_linux_create_lockfile(path);
+}
+
+/**
+ * Get some random data
+ * @param dst pointer to destination buffer
+ * @param length number of random bytes requested
+ * @return 0 if the random data was generated, -1 if an error happened
+ */
+static INLINE int
+os_core_get_random(void *dst, size_t length) {
+  return os_core_linux_get_random(dst, length);
+}
+
+/**
+ * Inline wrapper around gettimeofday
+ * @param tv pointer to target timeval object
+ * @return -1 if an error happened, 0 otherwise
+ */
+static INLINE int
+os_core_gettimeofday(struct timeval *tv) {
+  return gettimeofday(tv, NULL);
+}
+
+#endif /* OS_CORE_GENERIC_H_ */
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 9bad8fd..ea7e963 100644 (file)
@@ -3,6 +3,7 @@ add_subdirectory(cfg_compact)
 add_subdirectory(dlep)
 add_subdirectory(example)
 add_subdirectory(layer2info)
+add_subdirectory(layer2_config)
 add_subdirectory(layer2_generator)
 add_subdirectory(link_config)
 add_subdirectory(plugin_controller)
index 6a4c568..5ee4f9e 100644 (file)
@@ -67,6 +67,8 @@ static void _cleanup(void);
 static struct cfg_db *_cb_uci_load(const char *param, struct autobuf *log);
 static int _load_section(struct uci_section *sec, struct cfg_db *db, const char *type, const char *name, struct autobuf *log);
 
+static int _get_phy_ifname(char *phy_ifname, const char *ifname);
+
 static struct oonf_subsystem _oonf_cfg_uciloader_subsystem = {
   .name = OONF_CFG_UCILOADER_SUBSYSTEM,
   .descr = "OONF uci handler for configuration system",
@@ -92,6 +94,7 @@ static void
 _early_cfg_init(void)
 {
   cfg_io_add(oonf_cfg_get_instance(), &_cfg_io_uci);
+  cfg_set_ifname_handler(_get_phy_ifname);
 }
 
 /**
@@ -101,13 +104,14 @@ static void
 _cleanup(void)
 {
   cfg_io_remove(oonf_cfg_get_instance(), &_cfg_io_uci);
+  cfg_set_ifname_handler(NULL);
 }
 
 /*
  * Definition of the uci-io handler.
  *
- * This handler can read and write files and use a parser to
- * translate them into a configuration database (and the other way around)
+ * This handler can read files and use a parser to
+ * translate them into a configuration database
  *
  * The parameter of this parser has to be a filename
  */
@@ -177,6 +181,8 @@ _cb_uci_load(const char *param, struct autobuf *log) {
       }
     }
   }
+
+  uci_free_context(ctx);
   return db;
 
 uci_error:
@@ -243,3 +249,53 @@ _load_section(struct uci_section *sec, struct cfg_db *db, const char *type, cons
   }
   return 0;
 }
+
+/**
+ * Convert a logical interface name into a physical one
+ * @param phy_ifname buffer for physical interface name
+ * @param ifname logical interface name
+ * @return 0 if conversion was possible, negative if an error happened
+ */
+static int
+_get_phy_ifname(char *phy_ifname, const char *ifname) {
+  struct uci_context *ctx = NULL;
+  struct uci_package *p = NULL;
+  struct uci_section *sec;
+  struct uci_option *opt;
+
+  int result = 0;
+
+  ctx = uci_alloc_context();
+  if (!ctx) {
+    return -1;
+  }
+
+  if (uci_load(ctx, "/etc/config/network", &p)) {
+    result = -2;
+    goto uci_error;
+  }
+
+  sec = uci_lookup_section(ctx, p, ifname);
+  if (!sec) {
+    /* interface section does not exist */
+    result = -3;
+    goto uci_error;
+  }
+
+  if (!sec->type || strcmp(sec->type, "interface") != 0) {
+    result = -4;
+    goto uci_error;
+  }
+
+  opt = uci_lookup_option(ctx, sec, "ifname");
+  if (!opt) {
+    result = -5;
+    goto uci_error;
+  }
+
+  strscpy(phy_ifname, opt->v.string, IF_NAMESIZE);
+
+uci_error:
+  uci_free_context(ctx);
+  return result;
+}
index 9545fb7..a1df773 100644 (file)
@@ -56,6 +56,9 @@
 #include "dlep/dlep_writer.h"
 #include "dlep/dlep_extension.h"
 
+static int _process_interface_specific_update(
+    struct dlep_extension *ext, struct dlep_session *session);
+
 static struct avl_tree _extension_tree;
 
 static uint16_t *_id_array = NULL;
@@ -161,35 +164,11 @@ dlep_extension_get_ids(uint16_t *length) {
 int
 dlep_extension_router_process_peer_init_ack(
     struct dlep_extension *ext, struct dlep_session *session) {
-  struct oonf_layer2_net *l2net;
-  int result;
-
   if (session->restrict_signal != DLEP_PEER_INITIALIZATION_ACK) {
     /* ignore unless we are in initialization mode */
     return 0;
   }
-
-  l2net = oonf_layer2_net_add(session->l2_listener.name);
-  if (!l2net) {
-    OONF_INFO(session->log_source,
-        "Could not find l2net for interface");
-    return -1;
-  }
-
-  result = dlep_reader_map_l2neigh_data(l2net->neighdata, session, ext);
-  if (result) {
-    OONF_INFO(session->log_source, "tlv mapping for extension %d failed: %d",
-        ext->id, result);
-    return result;
-  }
-
-  result = dlep_reader_map_l2net_data(l2net->data, session, ext);
-  if (result) {
-    OONF_INFO(session->log_source, "tlv mapping for extension %d failed: %d",
-        ext->id, result);
-    return result;
-  }
-  return 0;
+  return _process_interface_specific_update(ext, session);
 }
 
 /**
@@ -202,34 +181,12 @@ dlep_extension_router_process_peer_init_ack(
 int
 dlep_extension_router_process_peer_update(
     struct dlep_extension *ext, struct dlep_session *session) {
-  struct oonf_layer2_net *l2net;
-  int result;
-
-  if (session->restrict_signal != DLEP_PEER_INITIALIZATION_ACK) {
-    /* ignore unless we are in initialization mode */
+  if (session->restrict_signal != DLEP_ALL_SIGNALS) {
+    /* ignore unless we have an established session */
     return 0;
   }
 
-  l2net = oonf_layer2_net_add(session->l2_listener.name);
-  if (!l2net) {
-    OONF_INFO(session->log_source, "Could not add l2net for new interface");
-    return -1;
-  }
-
-  result = dlep_reader_map_l2neigh_data(l2net->neighdata, session, ext);
-  if (result) {
-    OONF_INFO(session->log_source, "tlv mapping for extension %d failed: %d",
-        ext->id, result);
-    return result;
-  }
-
-  result = dlep_reader_map_l2net_data(l2net->data, session, ext);
-  if (result) {
-    OONF_INFO(session->log_source, "tlv mapping for extension %d failed: %d",
-        ext->id, result);
-    return result;
-  }
-  return 0;
+  return _process_interface_specific_update(ext, session);
 }
 
 /**
@@ -247,6 +204,11 @@ dlep_extension_router_process_destination(
   struct netaddr mac;
   int result;
 
+  if (session->restrict_signal != DLEP_ALL_SIGNALS) {
+    /* ignore unless we have an established session */
+    return 0;
+  }
+
   if (dlep_reader_mac_tlv(&mac, session, NULL)) {
     OONF_INFO(session->log_source, "mac tlv missing");
     return -1;
@@ -404,3 +366,38 @@ dlep_extension_radio_write_destination(struct dlep_extension *ext,
   }
   return 0;
 }
+
+/**
+ * Handle peer update and session init ACK for DLEP extension
+ * by automatically mapping oonf_layer2_data to DLEP TLVs
+ * @param ext dlep extension
+ * @param session dlep session
+ * @return -1 if an error happened, 0 otherwise
+ */
+static int
+_process_interface_specific_update(
+    struct dlep_extension *ext, struct dlep_session *session) {
+  struct oonf_layer2_net *l2net;
+  int result;
+
+  l2net = oonf_layer2_net_add(session->l2_listener.name);
+  if (!l2net) {
+    OONF_INFO(session->log_source, "Could not add l2net for new interface");
+    return -1;
+  }
+
+  result = dlep_reader_map_l2neigh_data(l2net->neighdata, session, ext);
+  if (result) {
+    OONF_INFO(session->log_source, "tlv mapping for extension %d failed: %d",
+        ext->id, result);
+    return result;
+  }
+
+  result = dlep_reader_map_l2net_data(l2net->data, session, ext);
+  if (result) {
+    OONF_INFO(session->log_source, "tlv mapping for extension %d failed: %d",
+        ext->id, result);
+    return result;
+  }
+  return 0;
+}
index 219d31b..0337ff0 100644 (file)
@@ -71,7 +71,8 @@ static const char _DLEP_PREFIX[] = DLEP_DRAFT_17_PREFIX;
  */
 int
 dlep_if_add(struct dlep_if *interf, const char *ifname,
-    uint32_t l2_origin, enum oonf_log_source log_src, bool radio) {
+    const struct oonf_layer2_origin *l2_origin,
+    enum oonf_log_source log_src, bool radio) {
   struct dlep_extension *ext;
 
   /* initialize key */
@@ -185,6 +186,11 @@ _cb_receive_udp(struct oonf_packet_socket *pkt,
     return;
   }
 
+  if (netaddr_socket_cmp(from, &pkt->local_socket) == 0) {
+    /* we hear outselves, ignore it */
+    return;
+  }
+
   if (memcmp(buffer, _DLEP_PREFIX, sizeof(_DLEP_PREFIX)-1) != 0) {
     OONF_WARN(interf->session.log_source,
         "Incoming UDP packet with unknown signature");
index bc43f63..207fd68 100644 (file)
@@ -81,7 +81,8 @@ struct dlep_if {
 };
 
 int dlep_if_add(struct dlep_if *interf, const char *ifname,
-    uint32_t l2_origin, enum oonf_log_source log_src, bool radio);
+    const struct oonf_layer2_origin *l2_origin,
+    enum oonf_log_source log_src, bool radio);
 void dlep_if_remove(struct dlep_if *interface);
 
 #endif /* DLEP_INTERFACE_H_ */
index a3ce080..2798ec8 100644 (file)
@@ -79,7 +79,7 @@ static enum dlep_parser_error _handle_extension(struct dlep_session *session,
 static enum dlep_parser_error _process_tlvs(struct dlep_session *,
     uint16_t signal_type, uint16_t signal_length, const uint8_t *tlvs);
 static void _send_terminate(struct dlep_session *session);
-static void _cb_destination_timeout(void *);
+static void _cb_destination_timeout(struct oonf_timer_instance *);
 
 static struct oonf_class _tlv_class = {
     .name = "dlep reader tlv",
@@ -119,7 +119,7 @@ dlep_session_init(void) {
  */
 int
 dlep_session_add(struct dlep_session *session, const char *l2_ifname,
-    uint32_t l2_origin, struct autobuf *out, bool radio,
+    const struct oonf_layer2_origin *l2_origin, struct autobuf *out, bool radio,
     enum oonf_log_source log_source) {
   struct dlep_session_parser *parser;
   struct dlep_extension *ext;
@@ -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) {
@@ -414,9 +414,9 @@ dlep_session_process_signal(struct dlep_session *session,
     return 0;
   }
 
-  OONF_DEBUG(session->log_source, "Process signal %u (length %u)"
-      " from %s (%" PRINTF_SIZE_T_SPECIFIER" bytes)",
-      signal_type, signal_length,
+  OONF_DEBUG_HEX(session->log_source, buffer, signal_length + 4,
+      "Process signal %u from %s (%" PRINTF_SIZE_T_SPECIFIER" bytes)",
+      signal_type,
       netaddr_socket_to_string(&nbuf, &session->remote_socket),
       length);
 
@@ -469,7 +469,6 @@ dlep_session_add_local_neighbor(struct dlep_session *session,
 
   /* initialize timer */
   local->_ack_timeout.class = &_destination_ack_class;
-  local->_ack_timeout.cb_context = local;
 
   /* initialize backpointer */
   local->session = session;
@@ -785,9 +784,6 @@ _process_tlvs(struct dlep_session *session,
   enum dlep_parser_error result;
   struct dlep_extension *ext;
 
-  OONF_DEBUG(session->log_source, "Parse signal %u with length %u",
-      signal_type, signal_length);
-
   /* start at the beginning of the tlvs */
   if ((result = _parse_tlvstream(session, tlvs, signal_length))) {
     OONF_DEBUG(session->log_source, "parse_tlvstream result: %d", result);
@@ -820,13 +816,13 @@ _send_terminate(struct dlep_session *session) {
 
 /**
  * Callback when a destination up/down signal times out
- * @param ptr local dlep neighbor
+ * @param ptr timer instance that fired
  */
 static void
-_cb_destination_timeout(void *ptr) {
+_cb_destination_timeout(struct oonf_timer_instance *ptr) {
   struct dlep_local_neighbor *local;
 
-  local = ptr;
+  local = container_of(ptr, struct dlep_local_neighbor, _ack_timeout);
   if (local->session->cb_destination_timeout) {
     local->session->cb_destination_timeout(local->session, local);
   }
index 0d7ab8a..9d9e8a3 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"
@@ -170,8 +169,8 @@ struct dlep_writer {
   /*! type of signal */
   uint16_t signal_type;
 
-  /*! pointer to first byte of signal */
-  char *signal_start_ptr;
+  /*! index of first byte of signal */
+  size_t signal_start;
 };
 
 /**
@@ -269,7 +268,7 @@ struct dlep_session {
   struct avl_tree local_neighbor_tree;
 
   /*! oonf layer2 origin for dlep session */
-  uint32_t l2_origin;
+  const struct oonf_layer2_origin *l2_origin;
 
   /*! send content of output buffer */
   void (*cb_send_buffer)(struct dlep_session *, int af_family);
@@ -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;
@@ -306,7 +305,7 @@ struct dlep_session {
 void dlep_session_init(void);
 
 int dlep_session_add(struct dlep_session *session,
-    const char *l2_ifname, uint32_t l2_origin,
+    const char *l2_ifname, const struct oonf_layer2_origin *l2_origin,
     struct autobuf *out, bool radio, enum oonf_log_source);
 void dlep_session_remove(struct dlep_session *session);
 void dlep_session_terminate(struct dlep_session *session);
index 88b99aa..6891118 100644 (file)
@@ -68,8 +68,7 @@ void
 dlep_writer_start_signal(struct dlep_writer *writer, uint16_t signal_type) {
 
   writer->signal_type = signal_type;
-  writer->signal_start_ptr =
-      abuf_getptr(writer->out) + abuf_getlen(writer->out);
+  writer->signal_start = abuf_getlen(writer->out);
 
   abuf_append_uint16(writer->out, htons(signal_type));
   abuf_append_uint16(writer->out, 0);
@@ -119,7 +118,8 @@ int
 dlep_writer_finish_signal(struct dlep_writer *writer,
     enum oonf_log_source source) {
   size_t length;
-  uint16_t buffer;
+  uint16_t tmp16;
+  char *dst;
 
   if (abuf_has_failed(writer->out)) {
     OONF_WARN(source, "Could not build signal: %u",
@@ -127,8 +127,7 @@ dlep_writer_finish_signal(struct dlep_writer *writer,
     return -1;
   }
 
-  length = (abuf_getptr(writer->out) + abuf_getlen(writer->out))
-      - writer->signal_start_ptr;
+  length = abuf_getlen(writer->out) - writer->signal_start;
   if (length > 65535 + 4) {
     OONF_WARN(source, "Signal %u became too long: %" PRINTF_SIZE_T_SPECIFIER,
         writer->signal_type, abuf_getlen(writer->out));
@@ -136,12 +135,13 @@ dlep_writer_finish_signal(struct dlep_writer *writer,
   }
 
   /* calculate network ordered size */
-  buffer = htons(length - 4);
+  tmp16 = htons(length - 4);
 
   /* put it into the signal */
-  memcpy(&writer->signal_start_ptr[2], &buffer, sizeof(buffer));
+  dst = abuf_getptr(writer->out);
+  memcpy(&dst[writer->signal_start + 2], &tmp16, sizeof(tmp16));
 
-  OONF_DEBUG_HEX(source, writer->signal_start_ptr, length,
+  OONF_DEBUG_HEX(source, &dst[writer->signal_start], length,
       "Finished signal %u:", writer->signal_type);
   return 0;
 }
index 74f845e..25565ca 100644 (file)
@@ -72,7 +72,6 @@ static const uint16_t _peer_initack_mandatory[] = {
     DLEP_MDRT_TLV,
     DLEP_CDRR_TLV,
     DLEP_CDRT_TLV,
-    DLEP_LATENCY_TLV,
 };
 
 /* peer update */
@@ -198,7 +197,7 @@ static struct dlep_neighbor_mapping _neigh_mappings[] = {
         .length        = 8,
 
         .mandatory     = true,
-        .default_value = 1000000,
+        .default_value = 0,
 
         .from_tlv      = dlep_reader_map_identity,
         .to_tlv        = dlep_writer_map_identity,
@@ -208,9 +207,6 @@ static struct dlep_neighbor_mapping _neigh_mappings[] = {
         .layer2   = OONF_LAYER2_NEIGH_LATENCY,
         .length   = 8,
 
-        .mandatory     = true,
-        .default_value = 0,
-
         .from_tlv      = dlep_reader_map_identity,
         .to_tlv        = dlep_writer_map_identity,
     },
index c9a7671..fa27cdd 100644 (file)
@@ -55,8 +55,8 @@
 
 #include "dlep/ext_base_proto/proto.h"
 
-static void _cb_local_heartbeat(void *);
-static void _cb_remote_heartbeat(void *);
+static void _cb_local_heartbeat(struct oonf_timer_instance *);
+static void _cb_remote_heartbeat(struct oonf_timer_instance *);
 
 /* peer discovery */
 
@@ -441,7 +441,6 @@ void
 dlep_base_proto_start_local_heartbeat(struct dlep_session *session) {
   /* timer for local heartbeat generation */
   session->local_event_timer.class = &_local_heartbeat_class;
-  session->local_event_timer.cb_context = session;
   oonf_timer_set(&session->local_event_timer,
       session->cfg.heartbeat_interval);
 }
@@ -454,7 +453,6 @@ void
 dlep_base_proto_start_remote_heartbeat(struct dlep_session *session) {
   /* timeout for remote heartbeats */
   session->remote_heartbeat_timeout.class = &_remote_heartbeat_class;
-  session->remote_heartbeat_timeout.cb_context = session;
   oonf_timer_set(&session->remote_heartbeat_timeout,
       session->remote_heartbeat_interval * 2);
 }
@@ -569,11 +567,13 @@ dlep_base_proto_write_mac_only(
 
 /**
  * Callback triggered when to generate a new heartbeat
- * @param ptr dlep session
+ * @param ptr timer instance that fired
  */
 static void
-_cb_local_heartbeat(void *ptr) {
-  struct dlep_session *session = ptr;
+_cb_local_heartbeat(struct oonf_timer_instance *ptr) {
+  struct dlep_session *session;
+
+  session = container_of(ptr, struct dlep_session, local_event_timer);
 
   dlep_session_generate_signal(session, DLEP_HEARTBEAT, NULL);
   session->cb_send_buffer(session, 0);
@@ -581,16 +581,31 @@ _cb_local_heartbeat(void *ptr) {
 
 /**
  * Callback triggered when the remote heartbeat times out
- * @param ptr dlep session
+ * @param ptr timer instance that fired
  */
 static void
-_cb_remote_heartbeat(void *ptr) {
-  struct dlep_session *session = ptr;
+_cb_remote_heartbeat(struct oonf_timer_instance *ptr) {
+  struct dlep_session *session;
 
-  /* stop local heartbeats */
-  oonf_timer_stop(&session->local_event_timer);
+  session = container_of(ptr, struct dlep_session, remote_heartbeat_timeout);
+
+  if (session->restrict_signal == DLEP_PEER_TERMINATION_ACK) {
+    /* peer termination ACK is missing! */
+
+    /* stop local heartbeats */
+    oonf_timer_stop(&session->local_event_timer);
 
-  /* terminate session */
-  dlep_session_generate_signal(session, DLEP_PEER_TERMINATION, NULL);
-  session->restrict_signal = DLEP_PEER_TERMINATION_ACK;
+    /* hard-terminate session */
+    if (session->cb_end_session) {
+      session->cb_end_session(session);
+    }
+  }
+  else {
+    /* soft-terminate session (send PEER_TERM) */
+    dlep_session_terminate(session);
+
+    /* set timeout for hard-termination */
+    oonf_timer_set(&session->remote_heartbeat_timeout,
+          session->remote_heartbeat_interval * 2);
+  }
 }
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 cfc2e68..422c2df 100644 (file)
@@ -61,7 +61,7 @@
 static void _cb_init_router(struct dlep_session *);
 static void _cb_apply_router(struct dlep_session *);
 static void _cb_cleanup_router(struct dlep_session *);
-static void _cb_create_peer_discovery(void *);
+static void _cb_create_peer_discovery(struct oonf_timer_instance *);
 
 static int _router_process_peer_offer(struct dlep_extension *, struct dlep_session *);
 static int _router_process_peer_init_ack(struct dlep_extension *, struct dlep_session *);
@@ -199,7 +199,6 @@ _cb_apply_router(struct dlep_session *session) {
      * so we need to send Peer Discovery messages
      */
     session->local_event_timer.class = &_peer_discovery_class;
-    session->local_event_timer.cb_context = session;
 
     OONF_DEBUG(session->log_source, "Activate discovery with interval %"
         PRIu64, session->cfg.discovery_interval);
@@ -220,6 +219,11 @@ _cb_cleanup_router(struct dlep_session *session) {
 
   l2net = oonf_layer2_net_get(session->l2_listener.name);
   if (l2net) {
+    /* remove DLEP mark from interface */
+    l2net->if_type = OONF_LAYER2_TYPE_UNDEFINED;
+    l2net->if_dlep = false;
+
+    /* and remove all DLEP data */
     oonf_layer2_net_remove(l2net, session->l2_origin);
   }
 
@@ -228,11 +232,13 @@ _cb_cleanup_router(struct dlep_session *session) {
 
 /**
  * Callback to generate regular peer discovery signals
- * @param ptr dlep session
+ * @param ptr timer instance that fired
  */
 static void
-_cb_create_peer_discovery(void *ptr) {
-  struct dlep_session *session = ptr;
+_cb_create_peer_discovery(struct oonf_timer_instance *ptr) {
+  struct dlep_session *session;
+
+  session = container_of(ptr, struct dlep_session, local_event_timer);
 
   OONF_DEBUG(session->log_source, "Generate peer discovery");
 
@@ -256,11 +262,12 @@ _router_process_peer_offer(
   struct dlep_router_if *router_if;
   union netaddr_socket local, remote;
   struct dlep_parser_value *value;
+  const struct os_interface_ip *ip;
   const struct netaddr *result = NULL;
   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 */
@@ -274,7 +281,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);
@@ -289,8 +296,9 @@ _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);
-      if (result) {
+      ip = os_interface_get_prefix_from_dst(&addr, ifdata);
+      if (ip) {
+        result = &ip->address;
         netaddr_socket_init(&remote, &addr, port, ifdata->index);
       }
     }
@@ -308,8 +316,9 @@ _router_process_peer_offer(
       /* TLS not supported at the moment */
     }
     else {
-      result = oonf_interface_get_prefix_from_dst(&addr, ifdata);
-      if (result) {
+      ip = os_interface_get_prefix_from_dst(&addr, ifdata);
+      if (ip) {
+        result = &ip->address;
         netaddr_socket_init(&remote, &addr, port, ifdata->index);
       }
     }
@@ -319,13 +328,14 @@ _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);
-    if (!result) {
+    ip = os_interface_get_prefix_from_dst(&addr, ifdata);
+    if (!ip) {
       /* no possible way to communicate */
       OONF_DEBUG(session->log_source,
           "No matching prefix for incoming connection found");
       return -1;
     }
+    result = &ip->address;
     netaddr_socket_init(&remote, &addr, port, ifdata->index);
   }
 
@@ -385,6 +395,11 @@ _router_process_peer_init_ack(
     return -1;
   }
 
+  /* mark interface as DLEP */
+  l2net->if_type = OONF_LAYER2_TYPE_WIRELESS;
+  l2net->if_dlep = true;
+
+  /* map user data into interface */
   result = dlep_reader_map_l2neigh_data(l2net->neighdata, session, _base);
   if (result) {
     OONF_INFO(session->log_source, "tlv mapping failed for extension %u: %u",
@@ -430,8 +445,11 @@ _router_process_peer_update(
     return -1;
   }
 
-  // we don't support IP address exchange at the moment
-  return 0;
+  /* we don't support IP address exchange at the moment */
+
+  /* generate ACK */
+  return dlep_session_generate_signal(
+      session, DLEP_PEER_UPDATE_ACK, NULL);
 }
 
 /**
@@ -488,6 +506,7 @@ _router_process_destination_up(
     return result;
   }
 
+  /* generate ACK */
   return dlep_session_generate_signal(
       session, DLEP_DESTINATION_UP_ACK, &mac);
 }
@@ -537,8 +556,9 @@ _router_process_destination_down(
   /* remove layer2 neighbor */
   oonf_layer2_neigh_remove(l2neigh, session->l2_origin);
 
+  /* generate ACK */
   return dlep_session_generate_signal(
-      session, DLEP_DESTINATION_UP_ACK, &mac);
+      session, DLEP_DESTINATION_DOWN_ACK, &mac);
 }
 
 /**
index 3b4ce6f..a5782d5 100644 (file)
@@ -89,7 +89,7 @@ static struct cfg_schema_entry _radio_entries[] = {
 
   CFG_MAP_INT32_MINMAX(dlep_radio_if, tcp_config.port, "session_port",
     "12345", "Server port for DLEP tcp sessions", 0, false, 1, 65535),
-  CFG_MAP_ACL_V46(dlep_radio_if, tcp_config.bindto, "session_bindto", "fe80::/10",
+  CFG_MAP_ACL_V46(dlep_radio_if, tcp_config.bindto, "session_bindto", "224.0.0.1\0fe80::/10",
       "Filter to determine the binding of the TCP server socket"),
   CFG_MAP_CLOCK_MINMAX(dlep_radio_if, interf.session.cfg.heartbeat_interval,
       "heartbeat_interval", "1.000",
@@ -98,9 +98,9 @@ static struct cfg_schema_entry _radio_entries[] = {
   CFG_MAP_BOOL(dlep_radio_if, interf.single_session, "single_session", "true",
       "Connect only to a single router"),
 
-  CFG_MAP_BOOL(dlep_radio_if, interf.session.cfg.send_proxied, "proxied", "false",
+  CFG_MAP_BOOL(dlep_radio_if, interf.session.cfg.send_proxied, "proxied", "true",
       "Report 802.11s proxied mac address for neighbors"),
-  CFG_MAP_BOOL(dlep_radio_if, interf.session.cfg.send_neighbors, "not_proxied", "true",
+  CFG_MAP_BOOL(dlep_radio_if, interf.session.cfg.send_neighbors, "not_proxied", "false",
       "Report direct neighbors"),
 };
 
@@ -180,10 +180,14 @@ _cleanup(void) {
 static void
 _cb_config_changed(void) {
   struct dlep_radio_if *interface;
+  const char *ifname;
+  char ifbuf[IF_NAMESIZE];
+
+  ifname = cfg_get_phy_if(ifbuf, _radio_section.section_name);
 
   if (!_radio_section.post) {
     /* remove old interface object */
-    interface = dlep_radio_get_by_layer2_if(_radio_section.section_name);
+    interface = dlep_radio_get_by_layer2_if(ifname);
     if (interface) {
       dlep_radio_remove_interface(interface);
     }
@@ -191,7 +195,7 @@ _cb_config_changed(void) {
   }
 
   /* get interface object or create one */
-  interface = dlep_radio_add_interface(_radio_section.section_name);
+  interface = dlep_radio_add_interface(ifname);
   if (!interface) {
     return;
   }
@@ -205,15 +209,15 @@ _cb_config_changed(void) {
   }
 
   if (!interface->interf.udp_config.interface[0]) {
-    strscpy(interface->interf.udp_config.interface,
-        _radio_section.section_name,
-        sizeof(interface->interf.udp_config.interface));
+    strscpy(interface->interf.udp_config.interface, ifname, IF_NAMESIZE);
+  }
+  else {
+    cfg_get_phy_if(interface->interf.udp_config.interface,
+        interface->interf.udp_config.interface);
   }
-
   /* apply interface name also to TCP socket */
   strscpy(interface->tcp_config.interface,
-      interface->interf.udp_config.interface,
-      sizeof(interface->tcp_config.interface));
+      interface->interf.udp_config.interface, IF_NAMESIZE);
 
   /* apply settings */
   dlep_radio_apply_interface_settings(interface);
index 15d85c9..d970e49 100644 (file)
@@ -220,7 +220,7 @@ dlep_radio_apply_interface_settings(struct dlep_radio_if *interface) {
   oonf_stream_apply_managed(&interface->tcp, &interface->tcp_config);
 
   avl_for_each_element(dlep_extension_get_tree(), ext, _node) {
-    if (ext->cb_session_apply_router) {
+    if (ext->cb_session_apply_radio) {
       ext->cb_session_apply_radio(&interface->interf.session);
     }
   }
index 7414703..f8ae32a 100644 (file)
@@ -81,7 +81,7 @@ static struct cfg_schema_entry _router_entries[] = {
   CFG_MAP_INT32_MINMAX(dlep_router_if, interf.udp_config.multicast_port, "discovery_port",
     DLEP_WELL_KNOWN_MULTICAST_PORT_TXT, "UDP port for discovery packets", 0, false, 1, 65535),
 
-  CFG_MAP_ACL_V46(dlep_router_if, interf.udp_config.bindto, "discovery_bindto", "fe80::/10",
+  CFG_MAP_ACL_V46(dlep_router_if, interf.udp_config.bindto, "discovery_bindto", "224.0.0.1\0fe80::/10",
     "Filter to determine the binding of the UDP discovery socket"),
 
   CFG_MAP_CLOCK_MIN(dlep_router_if, interf.session.cfg.discovery_interval,
@@ -97,6 +97,11 @@ static struct cfg_schema_entry _router_entries[] = {
   CFG_MAP_STRING_ARRAY(dlep_router_if, interf.udp_config.interface, "datapath_if", "",
       "Overwrite datapath interface for incoming dlep traffic, used for"
       " receiving DLEP data through out-of-band channel.", IF_NAMESIZE),
+
+  CFG_MAP_NETADDR_V46(dlep_router_if, connect_to_addr, "connect_to", "-",
+      "IP to directly connect to a known DLEP radio TCP socket", false, true),
+  CFG_MAP_INT32_MINMAX(dlep_router_if, connect_to_port, "connect_to_port", "1",
+      "TCP port to directly connect to a known DLEP radio TCP socket", 0, false, 1, 65535),
 };
 
 static struct cfg_schema_section _router_section = {
@@ -174,10 +179,14 @@ _cleanup(void) {
 static void
 _cb_config_changed(void) {
   struct dlep_router_if *interface;
+  const char *ifname;
+  char ifbuf[IF_NAMESIZE];
+
+  ifname = cfg_get_phy_if(ifbuf, _router_section.section_name);
 
   if (!_router_section.post) {
     /* remove old session object */
-    interface = dlep_router_get_by_layer2_if(_router_section.section_name);
+    interface = dlep_router_get_by_layer2_if(ifname);
     if (interface) {
       dlep_router_remove_interface(interface);
     }
@@ -185,7 +194,7 @@ _cb_config_changed(void) {
   }
 
   /* get session object or create one */
-  interface = dlep_router_add_interface(_router_section.section_name);
+  interface = dlep_router_add_interface(ifname);
   if (!interface) {
     return;
   }
@@ -204,6 +213,10 @@ _cb_config_changed(void) {
         _router_section.section_name,
         sizeof(interface->interf.udp_config.interface));
   }
+  else {
+    cfg_get_phy_if(interface->interf.udp_config.interface,
+        interface->interf.udp_config.interface);
+  }
 
   /* apply settings */
   dlep_router_apply_interface_settings(interface);
index 36dda73..4056226 100644 (file)
@@ -82,7 +82,11 @@ static struct oonf_class _router_if_class = {
 };
 
 static bool _shutting_down;
-static uint32_t _l2_origin;
+static struct oonf_layer2_origin _l2_origin = {
+  .name = "dlep router interface",
+  .proactive = true,
+  .priority = OONF_LAYER2_ORIGIN_RELIABLE,
+};
 
 /**
  * Initialize dlep router interface framework. This will also
@@ -103,7 +107,7 @@ dlep_router_interface_init(void) {
 
   _shutting_down = false;
 
-  _l2_origin = oonf_layer2_register_origin();
+  oonf_layer2_add_origin(&_l2_origin);
 }
 
 /**
@@ -121,6 +125,7 @@ dlep_router_interface_cleanup(void) {
   oonf_class_remove(&_router_if_class);
 
   dlep_router_session_cleanup();
+  oonf_layer2_remove_origin(&_l2_origin);
 }
 
 /**
@@ -173,7 +178,7 @@ dlep_router_add_interface(const char *ifname) {
   }
 
   if (dlep_if_add(&interface->interf, ifname,
-      _l2_origin, LOG_DLEP_ROUTER, false)) {
+      &_l2_origin, LOG_DLEP_ROUTER, false)) {
     oonf_class_free(&_router_if_class, interface);
     return NULL;
   }
@@ -182,7 +187,6 @@ dlep_router_add_interface(const char *ifname) {
   avl_insert(&_interface_tree, &interface->interf._node);
 
   OONF_DEBUG(LOG_DLEP_ROUTER, "Add session %s", ifname);
-
   return interface;
 }
 
@@ -211,10 +215,35 @@ 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 *os_if;
+  const struct os_interface_ip *result;
+  union netaddr_socket local, remote;
+#ifdef OONF_LOG_DEBUG_INFO
+  struct netaddr_str nbuf;
+#endif
+
   oonf_packet_apply_managed(&interf->interf.udp, &interf->interf.udp_config);
 
   _cleanup_interface(interf);
 
+  if (!netaddr_is_unspec(&interf->connect_to_addr)) {
+    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 = os_interface_get_prefix_from_dst(&interf->connect_to_addr, os_if);
+    if (result) {
+      /* initialize local and remote socket */
+      netaddr_socket_init(&local, &result->address, 0, os_if->index);
+      netaddr_socket_init(&remote,
+          &interf->connect_to_addr, interf->connect_to_port, os_if->index);
+
+      dlep_router_add_session(interf, &local, &remote);
+    }
+  }
+
   avl_for_each_element(dlep_extension_get_tree(), ext, _node) {
     if (ext->cb_session_apply_router) {
       ext->cb_session_apply_router(&interf->interf.session);
index ee6d2d4..d36fca7 100644 (file)
@@ -47,6 +47,7 @@
 #define DLEP_ROUTER_INTERFACE_H_
 
 #include "common/common_types.h"
+#include "common/netaddr.h"
 
 #include "dlep/dlep_session.h"
 #include "dlep/dlep_interface.h"
 struct dlep_router_if {
   /*! generic DLEP interface */
   struct dlep_if interf;
+
+  /*! IP address to directly connect router to */
+  struct netaddr connect_to_addr;
+
+  /*! TCP port to directly connect router to */
+  int32_t connect_to_port;
 };
 
 void dlep_router_interface_init(void);
index 53b8468..e81d484 100644 (file)
@@ -75,16 +75,12 @@ static struct oonf_class _router_session_class = {
   .size = sizeof(struct dlep_router_session),
 };
 
-static uint32_t _l2_origin;
-
 /**
  * Initialize dlep router session framework
  */
 void
 dlep_router_session_init(void) {
   oonf_class_add(&_router_session_class);
-
-  _l2_origin = oonf_layer2_register_origin();
 }
 
 /**
index 8e8e4d3..8960d18 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"
@@ -77,7 +77,7 @@ struct _eth_config {
 static int _init(void);
 static void _cleanup(void);
 
-static void _cb_transmission_event(void *);
+static void _cb_transmission_event(struct oonf_timer_instance *);
 static void _cb_config_changed(void);
 
 /* configuration */
@@ -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,
@@ -127,7 +127,12 @@ static struct oonf_timer_instance _transmission_timer = {
   .class = &_transmission_timer_info
 };
 
-static uint32_t _l2_origin;
+static struct oonf_layer2_origin _l2_origin = {
+  .name = "ethernet listener",
+  .priority = OONF_LAYER2_ORIGIN_UNRELIABLE,
+  .proactive = true,
+};
+
 static int _ioctl_sock;
 
 static int
@@ -139,14 +144,14 @@ _init(void) {
   }
 
   oonf_timer_add(&_transmission_timer_info);
-  _l2_origin = oonf_layer2_register_origin();
+  oonf_layer2_add_origin(&_l2_origin);
 
   return 0;
 }
 
 static void
 _cleanup(void) {
-  oonf_layer2_cleanup_origin(_l2_origin);
+  oonf_layer2_remove_origin(&_l2_origin);
 
   oonf_timer_stop(&_transmission_timer);
   oonf_timer_remove(&_transmission_timer_info);
@@ -154,10 +159,14 @@ _cleanup(void) {
   close(_ioctl_sock);
 }
 
+/**
+ * Callback for querying ethernet status
+ * @param ptr timer instance that fired
+ */
 static void
-_cb_transmission_event(void *ptr __attribute((unused))) {
+_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;
@@ -166,7 +175,7 @@ _cb_transmission_event(void *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;
@@ -175,17 +184,17 @@ _cb_transmission_event(void *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 */
@@ -194,8 +203,16 @@ _cb_transmission_event(void *ptr __attribute((unused))) {
       continue;
     }
 
+    /* get ethernet linkspeed */
+    ethspeed = ethtool_cmd_speed(&cmd);
+    if (ethspeed == 0 || ethspeed == (uint16_t)-1 || ethspeed == (uint32_t)-1) {
+      /* speed is not known */
+      continue;
+    }
+    ethspeed *= 1000 * 1000;
+
     /* 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;
     }
@@ -203,18 +220,15 @@ _cb_transmission_event(void *ptr __attribute((unused))) {
       l2net->if_type = OONF_LAYER2_TYPE_ETHERNET;
     }
 
-    /* get ethernet linkspeed */
-    ethspeed = ethtool_cmd_speed(&cmd);
-    ethspeed *= 1000 * 1000;
-
     /* 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);
+        &_l2_origin, ethspeed);
     oonf_layer2_set_value(&l2net->neighdata[OONF_LAYER2_NEIGH_TX_BITRATE],
-        _l2_origin, ethspeed);
+        &_l2_origin, ethspeed);
   }
 }
 
index 8fd540e..555f19c 100644 (file)
@@ -71,7 +71,7 @@ struct _example_config {
 static int _init(void);
 static void _cleanup(void);
 
-static void _cb_counter_event(void *);
+static void _cb_counter_event(struct oonf_timer_instance *);
 static void _cb_config_changed(void);
 
 /* configuration */
@@ -132,8 +132,12 @@ _cleanup(void) {
   oonf_timer_remove(&_counter_info);
 }
 
+/**
+ * callback of example timer
+ * @param ptr timer instance that fired
+ */
 static void
-_cb_counter_event(void *ptr __attribute((unused))) {
+_cb_counter_event(struct oonf_timer_instance *ptr __attribute((unused))) {
   _config.counter++;
 
   OONF_INFO(LOG_EXAMPLE, "Updated counter to: %"PRIu64, _config.counter);
diff --git a/src-plugins/generic/layer2_config/CMakeLists.txt b/src-plugins/generic/layer2_config/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b754db0
--- /dev/null
@@ -0,0 +1,5 @@
+# set library parameters
+SET (name layer2_config)
+
+# use generic plugin maker
+oonf_create_plugin("${name}" "${name}.c" "${name}.h" "")
diff --git a/src-plugins/generic/layer2_config/layer2_config.c b/src-plugins/generic/layer2_config/layer2_config.c
new file mode 100644 (file)
index 0000000..7424abc
--- /dev/null
@@ -0,0 +1,762 @@
+
+/*
+ * 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 "common/avl.h"
+#include "common/avl_comp.h"
+#include "common/common_types.h"
+#include "config/cfg_schema.h"
+#include "config/cfg_validate.h"
+#include "core/oonf_logging.h"
+#include "core/oonf_subsystem.h"
+#include "subsystems/oonf_class.h"
+#include "subsystems/oonf_layer2.h"
+#include "subsystems/oonf_timer.h"
+
+#include "layer2_config/layer2_config.h"
+
+/* definitions and constants */
+#define LOG_LAYER2_CONFIG _oonf_layer2_config_subsystem.logging
+
+enum l2_data_type {
+  L2_NET,
+  L2_DEF,
+  L2_NEIGH,
+};
+
+struct l2_config_data {
+  enum l2_data_type type;
+  struct netaddr mac;
+
+  int data_idx;
+  int64_t data;
+};
+
+struct l2_config_if_data {
+  char interf[IF_NAMESIZE];
+
+  struct oonf_timer_instance _reconfigure_timer;
+  struct avl_node _node;
+
+  size_t count;
+  struct l2_config_data d[0];
+};
+
+/* Prototypes */
+static int _init(void);
+static void _cleanup(void);
+
+static struct l2_config_if_data *_add_if_data(
+    const char *ifname, size_t data_count);
+static void _remove_if_data(struct l2_config_if_data *);
+
+static void _cb_update_l2net(void *);
+static void _cb_update_l2neigh(void *);
+static void _cb_reconfigure(struct oonf_timer_instance *);
+
+static int _parse_l2net_config(
+    struct l2_config_data *storage, const char *value);
+static int _parse_l2neigh_config(
+    struct l2_config_data *storage, const char *value);
+static void _configure_if_data(struct l2_config_if_data *if_data);
+
+static int _cb_validate_l2netdata(const struct cfg_schema_entry *entry,
+    const char *section_name, const char *value, struct autobuf *out);
+static int _cb_validate_l2defdata(const struct cfg_schema_entry *entry,
+    const char *section_name, const char *value, struct autobuf *out);
+static int _cb_validate_l2neighdata(const struct cfg_schema_entry *entry,
+    const char *section_name, const char *value, struct autobuf *out);
+
+static void _cb_valhelp_l2net(
+    const struct cfg_schema_entry *entry, struct autobuf *out);
+static void _cb_valhelp_l2def(
+    const struct cfg_schema_entry *entry, struct autobuf *out);
+static void _cb_valhelp_l2neigh(
+    const struct cfg_schema_entry *entry, struct autobuf *out);
+static void _create_neigh_help(struct autobuf *out, bool mac);
+
+static void _cb_config_changed(void);
+
+/* define configuration entries */
+
+/*! configuration validator for linkdata */
+#define CFG_VALIDATE_L2NETDATA(p_name, p_def, p_help, args...)         _CFG_VALIDATE(p_name, p_def, p_help, .cb_validate = _cb_validate_l2netdata, .cb_valhelp = _cb_valhelp_l2net, .list = true, ##args )
+#define CFG_VALIDATE_L2DEFDATA(p_name, p_def, p_help, args...)         _CFG_VALIDATE(p_name, p_def, p_help, .cb_validate = _cb_validate_l2defdata, .cb_valhelp = _cb_valhelp_l2def, .list = true, ##args )
+#define CFG_VALIDATE_L2NEIGHDATA(p_name, p_def, p_help, args...)         _CFG_VALIDATE(p_name, p_def, p_help, .cb_validate = _cb_validate_l2neighdata, .cb_valhelp = _cb_valhelp_l2neigh, .list = true, ##args )
+
+static struct cfg_schema_entry _l2_config_if_entries[] = {
+  [L2_NET] = CFG_VALIDATE_L2NETDATA("l2net", "",
+    "Sets an interface wide layer2 entry into the database."
+    " Parameters are the key of the interface data followed by the data."),
+  [L2_DEF] = CFG_VALIDATE_L2DEFDATA("l2default", "",
+    "Sets an interface wide default neighbor layer2 entry into the database."
+    " Parameters are the key of the neighbor data followed by the data."),
+  [L2_NEIGH] = CFG_VALIDATE_L2NEIGHDATA("l2neighbor", "",
+    "Sets an neighbor specific layer2 entry into the database."
+    " Parameters are the key of the neighbor data followed by the mac address and then the data."),
+};
+
+static struct cfg_schema_section _l2_config_section = {
+  .type = CFG_INTERFACE_SECTION,
+  .mode = CFG_INTERFACE_SECTION_MODE,
+  .cb_delta_handler = _cb_config_changed,
+  .entries = _l2_config_if_entries,
+  .entry_count = ARRAYSIZE(_l2_config_if_entries),
+};
+
+/* declare subsystem */
+static const char *_dependencies[] = {
+  OONF_LAYER2_SUBSYSTEM,
+  OONF_TIMER_SUBSYSTEM,
+};
+static struct oonf_subsystem _oonf_layer2_config_subsystem = {
+  .name = OONF_LAYER2_CONFIG_SUBSYSTEM,
+  .dependencies = _dependencies,
+  .dependencies_count = ARRAYSIZE(_dependencies),
+  .init = _init,
+  .cleanup = _cleanup,
+
+  .cfg_section = &_l2_config_section,
+};
+DECLARE_OONF_PLUGIN(_oonf_layer2_config_subsystem);
+
+/* originator for smooth set/remove of configured layer2 values */
+static struct oonf_layer2_origin _l2_origin_current = {
+  .name = "layer2 config",
+  .priority = OONF_LAYER2_ORIGIN_CONFIGURED,
+};
+static struct oonf_layer2_origin _l2_origin_old = {
+  .name = "layer2 config old",
+  .priority = OONF_LAYER2_ORIGIN_CONFIGURED,
+};
+
+/* listener for removal of layer2 data */
+static struct oonf_class_extension _l2net_listener = {
+  .ext_name = "link config listener",
+  .class_name = LAYER2_CLASS_NETWORK,
+
+  .cb_remove = _cb_update_l2net,
+  .cb_change = _cb_update_l2net,
+};
+static struct oonf_class_extension _l2neigh_listener = {
+  .ext_name = "link config listener",
+  .class_name = LAYER2_CLASS_NEIGHBOR,
+
+  .cb_remove = _cb_update_l2neigh,
+  .cb_change = _cb_update_l2neigh,
+};
+
+/* interface data */
+static struct avl_tree _if_data_tree;
+
+/* interface reconfiguration timer */
+static struct oonf_timer_class _reconfigure_timer = {
+  .name = "layer2 reconfiguration",
+  .callback = _cb_reconfigure,
+};
+
+/**
+ * Subsystem constructor
+ * @return always returns 0
+ */
+static int
+_init(void) {
+  oonf_layer2_add_origin(&_l2_origin_current);
+  oonf_layer2_add_origin(&_l2_origin_old);
+
+  oonf_class_extension_add(&_l2net_listener);
+  oonf_class_extension_add(&_l2neigh_listener);
+
+  oonf_timer_add(&_reconfigure_timer);
+
+  avl_init(&_if_data_tree, avl_comp_strcasecmp, false);
+  return 0;
+}
+
+/**
+ * Subsystem destructor
+ */
+static void
+_cleanup(void) {
+  struct l2_config_if_data *if_data, *if_data_it;
+
+  avl_for_each_element_safe(&_if_data_tree, if_data, _node, if_data_it) {
+    _remove_if_data(if_data);
+  }
+  oonf_timer_remove(&_reconfigure_timer);
+
+  oonf_class_extension_remove(&_l2net_listener);
+  oonf_class_extension_remove(&_l2neigh_listener);
+
+  oonf_layer2_remove_origin(&_l2_origin_current);
+  oonf_layer2_remove_origin(&_l2_origin_old);
+}
+
+/**
+ * Add a new layer2 config interface data
+ * @param ifname name of interface
+ * @param data_count number of data entries
+ * @return interface entry, NULL if out of memory
+ */
+static struct l2_config_if_data *
+_add_if_data(const char *ifname, size_t data_count) {
+  struct l2_config_if_data *if_data;
+
+  if_data = avl_find_element(&_if_data_tree, ifname, if_data, _node);
+  if (if_data) {
+    _remove_if_data(if_data);
+  }
+
+  if_data = calloc(1, sizeof(struct l2_config_if_data)
+      + data_count * sizeof(struct l2_config_data));
+  if (!if_data) {
+    OONF_WARN(LOG_LAYER2_CONFIG, "Out of memory for %"PRINTF_SIZE_T_SPECIFIER
+        " ifdata entries for interface %s", data_count, _l2_config_section.section_name);
+    return NULL;
+  }
+
+  /* hook into tree */
+  strscpy(if_data->interf, ifname, IF_NAMESIZE);
+  if_data->_node.key = if_data->interf;
+
+  avl_insert(&_if_data_tree, &if_data->_node);
+
+  /* initialize timer */
+  if_data->_reconfigure_timer.class = &_reconfigure_timer;
+
+  return if_data;
+}
+
+/**
+ * removes a layer2 config interface data
+ * @param if_data interface data
+ */
+static void
+_remove_if_data(struct l2_config_if_data *if_data) {
+  if (!avl_is_node_added(&if_data->_node)) {
+    return;
+  }
+
+  oonf_timer_stop(&if_data->_reconfigure_timer);
+  avl_remove(&_if_data_tree, &if_data->_node);
+}
+
+/**
+ * Callback when a layer2 network entry is changed/removed
+ * @param ptr l2net entry
+ */
+static void
+_cb_update_l2net(void *ptr) {
+  struct oonf_layer2_net *l2net;
+  struct l2_config_if_data *if_data;
+
+  l2net = ptr;
+
+  if_data = avl_find_element(&_if_data_tree, l2net->name, if_data, _node);
+  if (if_data && !oonf_timer_is_active(&if_data->_reconfigure_timer)) {
+    OONF_DEBUG(LOG_LAYER2_CONFIG, "Received update for l2net: %s", l2net->name);
+    oonf_timer_set(&if_data->_reconfigure_timer, LAYER2_RECONFIG_DELAY);
+  }
+}
+
+/**
+ * Callback when a layer2 neighbor entry is changed/removed
+ * @param ptr l2net entry
+ */
+static void
+_cb_update_l2neigh(void *ptr) {
+  struct oonf_layer2_neigh *l2neigh;
+  struct l2_config_if_data *if_data;
+
+  l2neigh = ptr;
+
+  if_data = avl_find_element(&_if_data_tree, l2neigh->network->name, if_data, _node);
+  if (if_data && !oonf_timer_is_active(&if_data->_reconfigure_timer)) {
+    OONF_DEBUG(LOG_LAYER2_CONFIG, "Received update for l2neigh: %s", l2neigh->network->name);
+    oonf_timer_set(&if_data->_reconfigure_timer, LAYER2_RECONFIG_DELAY);
+  }
+}
+
+/**
+ * Timer called for delayed layer2 config update
+ * @param timer timer entry
+ */
+static void
+_cb_reconfigure(struct oonf_timer_instance *timer) {
+  struct l2_config_if_data *if_data;
+
+  if_data = container_of(timer, typeof(*if_data), _reconfigure_timer);
+  _configure_if_data(if_data);
+}
+
+/**
+ * Configuration subsystem validator for linkdata
+ * @param entry
+ * @param section_name
+ * @param value
+ * @param out
+ * @return
+ */
+static int
+_cb_validate_l2netdata(const struct cfg_schema_entry *entry,
+    const char *section_name, const char *value, struct autobuf *out) {
+  enum oonf_layer2_network_index idx;
+  const char *ptr;
+
+  ptr = NULL;
+
+  /* search for network metadata index */
+  for (idx = 0; idx < OONF_LAYER2_NET_COUNT; idx++) {
+    if ((ptr = str_hasnextword(value, oonf_layer2_get_net_metadata(idx)->key))) {
+      break;
+    }
+  }
+
+  if (!ptr) {
+    cfg_append_printable_line(out, "First work of '%s' for entry '%s'"
+        " in section %s is unknown layer2 network key",
+        value, entry->key.entry, section_name);
+    return -1;
+  }
+
+  /* test if second word is a human readable number */
+  if (cfg_validate_int(out, section_name, entry->key.entry, ptr,
+      INT64_MIN, INT64_MAX, 8,
+      oonf_layer2_get_neigh_metadata(idx)->fraction,
+      oonf_layer2_get_neigh_metadata(idx)->binary)) {
+    return -1;
+  }
+  return 0;
+}
+
+/**
+ * Configuration subsystem validator for linkdata
+ * @param entry
+ * @param section_name
+ * @param value
+ * @param out
+ * @return
+ */
+static int
+_cb_validate_l2defdata(const struct cfg_schema_entry *entry,
+    const char *section_name, const char *value, struct autobuf *out) {
+  enum oonf_layer2_neighbor_index idx;
+  const char *ptr;
+
+  ptr = NULL;
+
+  /* search for network metadata index */
+  for (idx = 0; idx < OONF_LAYER2_NEIGH_COUNT; idx++) {
+    if ((ptr = str_hasnextword(value, oonf_layer2_get_neigh_metadata(idx)->key))) {
+      break;
+    }
+  }
+
+  if (!ptr) {
+    cfg_append_printable_line(out, "First work of '%s' for entry '%s'"
+        " in section %s is unknown layer2 neighbor key",
+        value, entry->key.entry, section_name);
+    return -1;
+  }
+
+  /* test if second word is a human readable number */
+  if (cfg_validate_int(out, section_name, entry->key.entry, ptr,
+      INT64_MIN, INT64_MAX, 8,
+      oonf_layer2_get_neigh_metadata(idx)->fraction,
+      oonf_layer2_get_neigh_metadata(idx)->binary)) {
+    return -1;
+  }
+  return 0;
+}
+
+/**
+ * Configuration subsystem validator for linkdata
+ * @param entry
+ * @param section_name
+ * @param value
+ * @param out
+ * @return
+ */
+static int
+_cb_validate_l2neighdata(const struct cfg_schema_entry *entry,
+    const char *section_name, const char *value, struct autobuf *out) {
+  static const int8_t MAC48 = AF_MAC48;
+  enum oonf_layer2_neighbor_index idx;
+  struct isonumber_str sbuf;
+  const char *ptr;
+
+  ptr = NULL;
+
+  /* search for network metadata index */
+  for (idx = 0; idx < OONF_LAYER2_NEIGH_COUNT; idx++) {
+    if ((ptr = str_hasnextword(value, oonf_layer2_get_neigh_metadata(idx)->key))) {
+      break;
+    }
+  }
+
+  if (!ptr) {
+    cfg_append_printable_line(out, "First work of '%s' for entry '%s'"
+        " in section %s is unknown layer2 neighbor key",
+        value, entry->key.entry, section_name);
+    return -1;
+  }
+
+  /* test if second word is a human readable number */
+  ptr = str_cpynextword(sbuf.buf, ptr, sizeof(sbuf));
+  if (cfg_validate_int(out, section_name, entry->key.entry, sbuf.buf,
+      INT64_MIN, INT64_MAX, 8,
+      oonf_layer2_get_neigh_metadata(idx)->fraction,
+      oonf_layer2_get_neigh_metadata(idx)->binary)) {
+    return -1;
+  }
+
+  if (!ptr) {
+    cfg_append_printable_line(out, "Mac address of neighbor missing for entry '%s'"
+        " in section %s", entry->key.entry, section_name);
+    return -1;
+  }
+
+  /* test if third word is a mac address */
+  if (cfg_validate_netaddr(out, section_name, entry->key.entry, ptr,
+      false, &MAC48, 1)) {
+    return -1;
+  }
+  return 0;
+}
+
+/**
+ * Parse the parameters of a layer2 network config entry
+ * @param storage buffer to store results
+ * @param value configuration string
+ * @return -1 if an error happened, 0 otherwise
+ */
+static int
+_parse_l2net_config(struct l2_config_data *storage, const char *value) {
+  const char *ptr;
+  int idx;
+
+  ptr = NULL;
+
+  /* search for network metadata index */
+  for (idx = 0; idx < OONF_LAYER2_NET_COUNT; idx++) {
+    if ((ptr = str_hasnextword(value, oonf_layer2_get_net_metadata(idx)->key))) {
+      break;
+    }
+  }
+
+  if (!ptr) {
+    return -1;
+  }
+
+  storage->data_idx = idx;
+
+  /* convert number */
+  return isonumber_to_s64(&storage->data, ptr,
+      oonf_layer2_get_net_metadata(idx)->fraction,
+      oonf_layer2_get_net_metadata(idx)->binary);
+}
+
+/**
+ * Parse the parameters of a layer2 neighbor config entry
+ * @param storage buffer to store results
+ * @param value configuration string
+ * @return -1 if an error happened, 0 otherwise
+ */
+static int
+_parse_l2neigh_config(struct l2_config_data *storage, const char *value) {
+  struct isonumber_str sbuf;
+  const char *ptr;
+  int idx;
+
+  ptr = NULL;
+
+  /* search for network metadata index */
+  for (idx = 0; idx < OONF_LAYER2_NEIGH_COUNT; idx++) {
+    if ((ptr = str_hasnextword(value, oonf_layer2_get_neigh_metadata(idx)->key))) {
+      break;
+    }
+  }
+
+  if (!ptr) {
+    return -1;
+  }
+
+  storage->data_idx = idx;
+
+  /* convert number */
+  ptr = str_cpynextword(sbuf.buf, ptr, sizeof(sbuf));
+  if (isonumber_to_s64(&storage->data, sbuf.buf,
+      oonf_layer2_get_neigh_metadata(idx)->fraction,
+      oonf_layer2_get_neigh_metadata(idx)->binary)) {
+    return -1;
+  }
+
+  if (ptr) {
+    if (netaddr_from_string(&storage->mac, ptr)) {
+      return -1;
+    }
+
+    if (netaddr_get_address_family(&storage->mac) == AF_MAC48) {
+      return 0;
+    }
+  }
+  netaddr_invalidate(&storage->mac);
+  return 0;
+}
+
+/**
+ * Apply a layer2 config interface to the l2 database
+ * @param if_data interface data
+ */
+static void
+_configure_if_data(struct l2_config_if_data *if_data) {
+  struct oonf_layer2_neigh *l2neigh;
+  struct oonf_layer2_net *l2net;
+  struct l2_config_data *entry;
+  size_t i;
+
+
+  l2net = oonf_layer2_net_get(if_data->interf);
+  if (!l2net && if_data->count > 0) {
+    l2net = oonf_layer2_net_add(if_data->interf);
+    if (!l2net) {
+      return;
+    }
+  }
+
+  /* relabel old entries */
+  if (l2net) {
+    oonf_layer2_net_relabel(l2net, &_l2_origin_old, &_l2_origin_current);
+
+    for (i=0; i<if_data->count; i++) {
+      entry = &if_data->d[i];
+
+      switch (entry->type) {
+        case L2_NET:
+          oonf_layer2_set_value(&l2net->data[entry->data_idx],
+              &_l2_origin_current, entry->data);
+          break;
+        case L2_DEF:
+          oonf_layer2_set_value(&l2net->neighdata[entry->data_idx],
+              &_l2_origin_current, entry->data);
+          break;
+        case L2_NEIGH:
+          l2neigh = oonf_layer2_neigh_add(l2net, &entry->mac);
+          if (l2neigh) {
+            oonf_layer2_set_value(&l2neigh->data[entry->data_idx],
+                &_l2_origin_current, entry->data);
+          }
+          break;
+        default:
+          break;
+      }
+    }
+
+    /* remove old data */
+    oonf_layer2_net_remove(l2net, &_l2_origin_old);
+  }
+
+  /* stop update timer */
+  oonf_timer_stop(&if_data->_reconfigure_timer);
+}
+
+/**
+ * Create a help text for the l2net configuration parameter
+ * @param entry configuration entry
+ * @param out help output
+ */
+static void
+_cb_valhelp_l2net(const struct cfg_schema_entry *entry __attribute((unused)),
+    struct autobuf *out) {
+  size_t i;
+
+  abuf_puts(out, "    Parameter has the form '<l2net-key> <value>\n");
+  abuf_puts(out, "    <l2net-key> is one of the following list;\n");
+
+  for (i=0; i<OONF_LAYER2_NET_COUNT; i++) {
+    abuf_appendf(out, "        %s\n",
+        oonf_layer2_get_net_metadata(i)->key);
+  }
+
+  abuf_puts(out, "    <value> is an numeric value (with optional iso prefix)\n");
+}
+
+/**
+ * Create a help text for the l2default configuration parameter
+ * @param entry configuration entry
+ * @param out help output
+ */
+static void
+_cb_valhelp_l2def(const struct cfg_schema_entry *entry __attribute((unused)),
+    struct autobuf *out) {
+  _create_neigh_help(out, false);
+}
+
+/**
+ * Create a help text for the l2neighbor configuration parameter
+ * @param entry configuration entry
+ * @param out help output
+ */
+static void
+_cb_valhelp_l2neigh(const struct cfg_schema_entry *entry __attribute((unused)),
+    struct autobuf *out) {
+  _create_neigh_help(out, true);
+}
+
+/**
+ * Create a help text for the l2default and l2neighbor
+ * configuration parameter
+ * @param out help output
+ */
+static void
+_create_neigh_help(struct autobuf *out, bool mac) {
+  size_t i;
+
+
+  abuf_appendf(out, "    Parameter has the form '<l2neigh-key> <value>%s\n",
+      mac ? " <neighbor mac>" : "");
+  abuf_puts(out, "    <l2neigh-key> is one of the following list;\n");
+
+  for (i=0; i<OONF_LAYER2_NEIGH_COUNT; i++) {
+    abuf_appendf(out, "        %s\n",
+        oonf_layer2_get_neigh_metadata(i)->key);
+  }
+
+  abuf_puts(out, "    <value> is an numeric value (with optional iso prefix)\n");
+  if (mac) {
+    abuf_puts(out, "    <mac> is the ethernet mac address of the neighbor\n");
+  }
+}
+
+
+/**
+ * Parse configuration change
+ */
+static void
+_cb_config_changed(void) {
+  struct l2_config_if_data *if_data;
+  struct cfg_entry *l2net_entry, *l2def_entry, *l2neigh_entry;
+  char ifbuf[IF_NAMESIZE];
+  const char *ifname;
+  char *txt_value;
+  size_t i, total;
+
+  ifname = cfg_get_phy_if(ifbuf, _l2_config_section.section_name);
+  if_data = avl_find_element(&_if_data_tree, ifname, if_data, _node);
+  if (if_data) {
+    _remove_if_data(if_data);
+  }
+
+  if (!_l2_config_section.post) {
+    /* section was removed */
+     return;
+  }
+
+  l2net_entry = cfg_db_get_entry(_l2_config_section.post,
+      _l2_config_if_entries[L2_NET].key.entry);
+  l2def_entry = cfg_db_get_entry(_l2_config_section.post,
+      _l2_config_if_entries[L2_DEF].key.entry);
+  l2neigh_entry = cfg_db_get_entry(_l2_config_section.post,
+      _l2_config_if_entries[L2_NEIGH].key.entry);
+
+  /* calculate number of settings */
+  total = 0;
+  if (l2net_entry) {
+    total += strarray_get_count(&l2net_entry->val);
+  }
+  if (l2def_entry) {
+    total += strarray_get_count(&l2def_entry->val);
+  }
+  if (l2neigh_entry) {
+    total += strarray_get_count(&l2neigh_entry->val);
+  }
+
+  if_data = _add_if_data(_l2_config_section.section_name, total);
+  if (!if_data) {
+    OONF_WARN(LOG_LAYER2_CONFIG, "Out of memory for %"PRINTF_SIZE_T_SPECIFIER
+        " ifdata entries for interface %s", total, _l2_config_section.section_name);
+    return;
+  }
+
+  /* initialize header */
+  strscpy(if_data->interf, _l2_config_section.section_name, IF_NAMESIZE);
+  if_data->_node.key = if_data->interf;
+
+  avl_insert(&_if_data_tree, &if_data->_node);
+
+  /* initialize data */
+  i = 0;
+  if (l2net_entry) {
+    /* parse layer2 network data */
+    strarray_for_each_element(&l2net_entry->val, txt_value) {
+      if (!_parse_l2net_config(&if_data->d[i], txt_value)) {
+        if_data->d[i].type = L2_NET;
+        i++;
+      }
+    }
+  }
+  if (l2def_entry) {
+    /* parse layer2 default data */
+    strarray_for_each_element(&l2def_entry->val, txt_value) {
+      if (!_parse_l2neigh_config(&if_data->d[i], txt_value)) {
+        if_data->d[i].type = L2_DEF;
+        i++;
+      }
+    }
+  }
+  if (l2neigh_entry) {
+    /* parse layer2 network data */
+    strarray_for_each_element(&l2neigh_entry->val, txt_value) {
+      if (!_parse_l2neigh_config(&if_data->d[i], txt_value)) {
+        if_data->d[i].type = L2_NEIGH;
+        i++;
+      }
+    }
+  }
+
+  if_data->count = i;
+
+  /* reconfigure layer2 database */
+  _configure_if_data(if_data);
+}
  * @file
  */
 
-#include <sys/file.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
+#ifndef OONF_LAYER2_CONFIG_H_
+#define OONF_LAYER2_CONFIG_H_
 
-#include "core/os_core.h"
+/*! subsystem identifier */
+#define OONF_LAYER2_CONFIG_SUBSYSTEM "layer2_config"
 
-/**
- * Create a lock file of a certain name
- * @param path name of lockfile including path
- * @return 0 if the lock was created successfully, false otherwise
- */
-int
-os_core_create_lockfile(const char *path) {
-  int lock_fd;
-
-  /* create file for lock */
-  lock_fd = open(path, O_RDWR | O_CREAT, S_IRWXU);
-  if (lock_fd == -1) {
-    return -1;
-  }
-
-  if (flock(lock_fd, LOCK_EX | LOCK_NB)) {
-    close(lock_fd);
-    return -1;
-  }
+enum {
+  LAYER2_RECONFIG_DELAY = 500
+};
 
-  /* lock will be released when process ends */
-  return 0;
-}
+#endif /* OONF_LAYER2_CONFIG_H_ */
index c52ee25..ed45565 100644 (file)
@@ -67,7 +67,7 @@
 static int _init(void);
 static void _cleanup(void);
 
-static void _cb_l2gen_event(void *ptr);
+static void _cb_l2gen_event(struct oonf_timer_instance *);
 
 static void _cb_config_changed(void);
 
@@ -146,7 +146,11 @@ static struct oonf_subsystem _layer2_generator_subsystem = {
 };
 DECLARE_OONF_PLUGIN(_layer2_generator_subsystem);
 
-static uint32_t _origin = 0;
+static struct oonf_layer2_origin _origin = {
+  .name = "layer2 generator",
+  .proactive = true,
+  .priority = OONF_LAYER2_ORIGIN_CONFIGURED,
+};
 
 /**
  * Constructor of plugin
@@ -156,6 +160,7 @@ static int
 _init(void) {
   memset(&_l2gen_config, 0, sizeof(_l2gen_config));
 
+  oonf_layer2_add_origin(&_origin);
   oonf_timer_add(&_l2gen_timer_info);
   oonf_timer_start(&_l2gen_timer, 5000);
   return 0;
@@ -166,18 +171,18 @@ _init(void) {
  */
 static void
 _cleanup(void) {
-  if (_origin) {
-    oonf_layer2_cleanup_origin(_origin);
-    _origin = 0;
-  }
-
+  oonf_layer2_remove_origin(&_origin);
   oonf_timer_stop(&_l2gen_timer);
   oonf_timer_remove(&_l2gen_timer_info);
 }
 
 
+/**
+ * Callback for generating new layer2 test data
+ * @param ptr timer instance that fired
+ */
 static void
-_cb_l2gen_event(void *ptr __attribute((unused))) {
+_cb_l2gen_event(struct oonf_timer_instance *ptr __attribute((unused))) {
   static uint64_t event_counter = 100;
   enum oonf_layer2_network_index net_idx;
   enum oonf_layer2_neighbor_index neigh_idx;
@@ -187,7 +192,7 @@ _cb_l2gen_event(void *ptr __attribute((unused))) {
   struct netaddr_str buf1;
 #endif
 
-  if (_origin == 0) {
+  if (oonf_layer2_origin_is_added(&_origin)) {
     return;
   }
   
@@ -209,14 +214,15 @@ _cb_l2gen_event(void *ptr __attribute((unused))) {
   net->last_seen = oonf_clock_getNow();
 
   for (net_idx=0; net_idx<OONF_LAYER2_NET_COUNT; net_idx++) {
-    oonf_layer2_set_value(&net->data[net_idx], _origin, event_counter);
+    oonf_layer2_set_value(&net->data[net_idx], &_origin, event_counter);
   }
   for (neigh_idx=0; neigh_idx<OONF_LAYER2_NEIGH_COUNT; neigh_idx++) {
-    oonf_layer2_set_value(&net->neighdata[neigh_idx], _origin, event_counter);
+    oonf_layer2_set_value(&net->neighdata[neigh_idx], &_origin, event_counter);
   }
 
   if (oonf_layer2_net_commit(net)) {
     /* something bad has happened, l2net was removed */
+    OONF_WARN(LOG_L2GEN, "Could not commit interface %s", net->name);
     return;
   }
 
@@ -227,13 +233,13 @@ _cb_l2gen_event(void *ptr __attribute((unused))) {
   }
 
   if (netaddr_get_address_family(&_l2gen_config.destination) == AF_MAC48) {
-    oonf_layer2_destination_add(neigh, &_l2gen_config.destination, _origin);
+    oonf_layer2_destination_add(neigh, &_l2gen_config.destination, &_origin);
   }
   memcpy(&neigh->addr, &_l2gen_config.neighbor, sizeof(neigh->addr));
   neigh->last_seen = oonf_clock_getNow();
 
   for (neigh_idx = 0; neigh_idx < OONF_LAYER2_NEIGH_COUNT; neigh_idx++) {
-    oonf_layer2_set_value(&neigh->data[neigh_idx], _origin, event_counter);
+    oonf_layer2_set_value(&neigh->data[neigh_idx], &_origin, event_counter);
   }
   oonf_layer2_neigh_commit(neigh);
 }
@@ -247,14 +253,16 @@ _cb_config_changed(void) {
     return;
   }
 
-  OONF_DEBUG(LOG_L2GEN, "Generator is now %s\n", _l2gen_config.active ? "active" : "inactive");
+  cfg_get_phy_if(_l2gen_config.interface, _l2gen_config.interface);
+
+  OONF_DEBUG(LOG_L2GEN, "Generator is now %s for interface %s\n",
+      _l2gen_config.active ? "active" : "inactive", _l2gen_config.interface);
   
-  if (_origin == 0 && _l2gen_config.active) {
-    _origin = oonf_layer2_register_origin();
+  if (!oonf_layer2_origin_is_added(&_origin) && _l2gen_config.active) {
+    oonf_layer2_add_origin(&_origin);
   }
-  else if (_origin != 0 && !_l2gen_config.active) {
-    oonf_layer2_cleanup_origin(_origin);
-    _origin = 0;
+  else if (oonf_layer2_origin_is_added(&_origin) && !_l2gen_config.active) {
+    oonf_layer2_remove_origin(&_origin);
   }
   
   /* set new interval */
index d8a25a9..dfa57aa 100644 (file)
@@ -71,12 +71,15 @@ static void _cleanup(void);
 static enum oonf_telnet_result _cb_layer2info(struct oonf_telnet_data *con);
 static enum oonf_telnet_result _cb_layer2info_help(struct oonf_telnet_data *con);
 
-static void _initialize_interface_values(struct oonf_layer2_net *net);
-static void _initialize_net_data_values(struct oonf_viewer_template *template,
-    struct isonumber_str *dst, struct oonf_layer2_data *data);
-static void _initialize_net_data_values(struct oonf_viewer_template *template,
-    struct isonumber_str *dst, struct oonf_layer2_data *data);
-static void _initialize_neighbor_values(struct oonf_layer2_neigh *neigh);
+static void _initialize_if_data_values(struct oonf_viewer_template *template,
+    struct oonf_layer2_data *data);
+static void _initialize_if_origin_values(struct oonf_layer2_data *data);
+static void _initialize_if_values(struct oonf_layer2_net *net);
+
+static void _initialize_neigh_data_values(struct oonf_viewer_template *template,
+    struct oonf_layer2_data *data);
+static void _initialize_neigh_origin_values(struct oonf_layer2_data *data);
+static void _initialize_neigh_values(struct oonf_layer2_neigh *neigh);
 
 static int _cb_create_text_interface(struct oonf_viewer_template *);
 static int _cb_create_text_neighbor(struct oonf_viewer_template *);
@@ -98,6 +101,9 @@ static int _cb_create_text_dst(struct oonf_viewer_template *);
 /*! template key for interface type */
 #define KEY_IF_TYPE                     "if_type"
 
+/*! template key for DLEP interface */
+#define KEY_IF_DLEP                     "if_dlep"
+
 /*! template key for interface identifier */
 #define KEY_IF_IDENT                    "if_ident"
 
@@ -119,6 +125,9 @@ static int _cb_create_text_dst(struct oonf_viewer_template *);
 /*! template key for destination address */
 #define KEY_DST_ADDR                    "dst_addr"
 
+/*! template key for destination origin */
+#define KEY_DST_ORIGIN                  "dst_origin"
+
 
 /*! string prefix for all interface keys */
 #define KEY_IF_PREFIX                   "if_"
@@ -126,6 +135,9 @@ static int _cb_create_text_dst(struct oonf_viewer_template *);
 /*! string prefix for all neighbor keys */
 #define KEY_NEIGH_PREFIX                "neigh_"
 
+/*! string suffix for all data originators */
+#define KEY_ORIGIN_SUFFIX               "_origin"
+
 /*
  * buffer space for values that will be assembled
  * into the output of the plugin
@@ -133,17 +145,20 @@ static int _cb_create_text_dst(struct oonf_viewer_template *);
 static char                             _value_if[IF_NAMESIZE];
 static char                             _value_if_index[12];
 static char                             _value_if_type[16];
+static char                             _value_if_dlep[TEMPLATE_JSON_BOOL_LENGTH];
 static char                             _value_if_ident[33];
 static struct netaddr_str               _value_if_ident_addr;
 static struct netaddr_str               _value_if_local_addr;
 static struct isonumber_str             _value_if_lastseen;
 static struct isonumber_str             _value_if_data[OONF_LAYER2_NET_COUNT];
-
+static char                             _value_if_origin[OONF_LAYER2_NET_COUNT][IF_NAMESIZE];
 static struct netaddr_str               _value_neigh_addr;
 static struct isonumber_str             _value_neigh_lastseen;
 static struct isonumber_str             _value_neigh_data[OONF_LAYER2_NEIGH_COUNT];
+static char                             _value_neigh_origin[OONF_LAYER2_NEIGH_COUNT][IF_NAMESIZE];
 
 static struct netaddr_str               _value_dst_addr;
+static char                             _value_dst_origin[TEMPLATE_JSON_BOOL_LENGTH];
 
 /* definition of the template data entries for JSON and table output */
 static struct abuf_template_data_entry _tde_if_key[] = {
@@ -154,12 +169,14 @@ static struct abuf_template_data_entry _tde_if_key[] = {
 
 static struct abuf_template_data_entry _tde_if[] = {
     { KEY_IF_TYPE, _value_if_type, true },
+    { KEY_IF_DLEP, _value_if_dlep, true },
     { KEY_IF_IDENT, _value_if_ident, true },
     { KEY_IF_IDENT_ADDR, _value_if_ident_addr.buf, true },
     { KEY_IF_LASTSEEN, _value_if_lastseen.buf, false },
 };
 
 static struct abuf_template_data_entry _tde_if_data[OONF_LAYER2_NET_COUNT];
+static struct abuf_template_data_entry _tde_if_origin[OONF_LAYER2_NET_COUNT];
 
 static struct abuf_template_data_entry _tde_neigh_key[] = {
     { KEY_NEIGH_ADDR, _value_neigh_addr.buf, true },
@@ -170,10 +187,14 @@ static struct abuf_template_data_entry _tde_neigh[] = {
 };
 
 static struct abuf_template_data_entry _tde_neigh_data[OONF_LAYER2_NEIGH_COUNT];
+static struct abuf_template_data_entry _tde_neigh_origin[OONF_LAYER2_NEIGH_COUNT];
 
 static struct abuf_template_data_entry _tde_dst_key[] = {
     { KEY_DST_ADDR, _value_dst_addr.buf, true },
 };
+static struct abuf_template_data_entry _tde_dst[] = {
+    { KEY_DST_ORIGIN, _value_dst_origin, true },
+};
 
 static struct abuf_template_storage _template_storage;
 static struct autobuf _key_storage;
@@ -183,21 +204,25 @@ static struct abuf_template_data _td_if[] = {
     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
     { _tde_if, ARRAYSIZE(_tde_if) },
     { _tde_if_data, ARRAYSIZE(_tde_if_data) },
+    { _tde_if_origin, ARRAYSIZE(_tde_if_origin) },
 };
 static struct abuf_template_data _td_neigh[] = {
     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
     { _tde_neigh_key, ARRAYSIZE(_tde_neigh_key) },
     { _tde_neigh, ARRAYSIZE(_tde_neigh) },
     { _tde_neigh_data, ARRAYSIZE(_tde_neigh_data) },
+    { _tde_neigh_origin, ARRAYSIZE(_tde_neigh_origin) },
 };
 static struct abuf_template_data _td_default[] = {
     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
     { _tde_neigh_data, ARRAYSIZE(_tde_neigh_data) },
+    { _tde_neigh_origin, ARRAYSIZE(_tde_neigh_origin) },
 };
 static struct abuf_template_data _td_dst[] = {
     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
     { _tde_neigh_key, ARRAYSIZE(_tde_neigh_key) },
     { _tde_dst_key, ARRAYSIZE(_tde_dst_key) },
+    { _tde_dst, ARRAYSIZE(_tde_dst) },
 };
 
 /* OONF viewer templates (based on Template Data arrays) */
@@ -272,6 +297,16 @@ _init(void) {
     abuf_puts(&_key_storage, KEY_IF_PREFIX);
     abuf_puts(&_key_storage, oonf_layer2_get_net_metadata(i)->key);
     abuf_memcpy(&_key_storage, "\0", 1);
+
+    _tde_if_origin[i].key =
+        abuf_getptr(&_key_storage) + abuf_getlen(&_key_storage);
+    _tde_if_origin[i].value = _value_if_origin[i];
+    _tde_if_origin[i].string = true;
+
+    abuf_puts(&_key_storage, KEY_IF_PREFIX);
+    abuf_puts(&_key_storage, oonf_layer2_get_net_metadata(i)->key);
+    abuf_puts(&_key_storage, KEY_ORIGIN_SUFFIX);
+    abuf_memcpy(&_key_storage, "\0", 1);
   }
 
   for (i=0; i<OONF_LAYER2_NEIGH_COUNT; i++) {
@@ -283,6 +318,16 @@ _init(void) {
     abuf_puts(&_key_storage, KEY_NEIGH_PREFIX);
     abuf_puts(&_key_storage, oonf_layer2_get_neigh_metadata(i)->key);
     abuf_memcpy(&_key_storage, "\0", 1);
+
+    _tde_neigh_origin[i].key =
+        abuf_getptr(&_key_storage) + abuf_getlen(&_key_storage);
+    _tde_neigh_origin[i].value = _value_neigh_origin[i];
+    _tde_neigh_origin[i].string = true;
+
+    abuf_puts(&_key_storage, KEY_NEIGH_PREFIX);
+    abuf_puts(&_key_storage, oonf_layer2_get_neigh_metadata(i)->key);
+    abuf_puts(&_key_storage, KEY_ORIGIN_SUFFIX);
+    abuf_memcpy(&_key_storage, "\0", 1);
   }
 
   oonf_telnet_add(&_telnet_commands[0]);
@@ -327,15 +372,17 @@ _cb_layer2info_help(struct oonf_telnet_data *con) {
  * @param net pointer to layer2 interface
  */
 static void
-_initialize_interface_values(struct oonf_layer2_net *net) {
-  struct os_interface_data *data;
+_initialize_if_values(struct oonf_layer2_net *net) {
+  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);
+  strscpy(_value_if_type, oonf_layer2_get_network_type(net->if_type), IF_NAMESIZE);
+  strscpy(_value_if_dlep, json_getbool(net->if_dlep), TEMPLATE_JSON_BOOL_LENGTH);
 
   if (net->last_seen) {
     oonf_clock_toIntervalString(&_value_if_lastseen,
@@ -351,19 +398,17 @@ _initialize_interface_values(struct oonf_layer2_net *net) {
  * @param template viewer template
  * @param dst array of destination buffers
  * @param data array of data objects
- * @param meta array of metadata description of objects
- * @param count number of objects in each array
  */
 static void
-_initialize_net_data_values(struct oonf_viewer_template *template,
-    struct isonumber_str *dst, struct oonf_layer2_data *data) {
+_initialize_if_data_values(struct oonf_viewer_template *template,
+    struct oonf_layer2_data *data) {
   size_t i;
 
-  memset(dst, 0, sizeof(*dst) * OONF_LAYER2_NET_COUNT);
+  memset(_value_if_data, 0, sizeof(_value_if_data));
 
   for (i=0; i<OONF_LAYER2_NET_COUNT; i++) {
     if (oonf_layer2_has_value(&data[i])) {
-      isonumber_from_s64(&dst[i], oonf_layer2_get_value(&data[i]),
+      isonumber_from_s64(&_value_if_data[i], oonf_layer2_get_value(&data[i]),
           oonf_layer2_get_net_metadata(i)->unit,
           oonf_layer2_get_net_metadata(i)->fraction,
           oonf_layer2_get_net_metadata(i)->binary,
@@ -372,6 +417,40 @@ _initialize_net_data_values(struct oonf_viewer_template *template,
   }
 }
 
+/**
+ * Initialize the network origin buffers for an array of layer2 data objects
+ * @param data array of data objects
+ */
+static void
+_initialize_if_origin_values(struct oonf_layer2_data *data) {
+  size_t i;
+
+  memset(_value_if_origin, 0, sizeof(_value_if_origin));
+
+  for (i=0; i<OONF_LAYER2_NET_COUNT; i++) {
+    if (oonf_layer2_has_value(&data[i])) {
+      strscpy(_value_if_origin[i], oonf_layer2_get_origin(&data[i])->name, IF_NAMESIZE);
+    }
+  }
+}
+
+/**
+ * Initialize the value buffers for a layer2 neighbor
+ * @param neigh layer2 neighbor
+ */
+static void
+_initialize_neigh_values(struct oonf_layer2_neigh *neigh) {
+  netaddr_to_string(&_value_neigh_addr, &neigh->addr);
+
+  if (neigh->last_seen) {
+    oonf_clock_toIntervalString(&_value_neigh_lastseen,
+        -oonf_clock_get_relative(neigh->last_seen));
+  }
+  else {
+    _value_neigh_lastseen.buf[0] = 0;
+  }
+}
+
 /**
  * Initialize the value buffers for an array of layer2 data objects
  * @param template viewer template
@@ -382,14 +461,15 @@ _initialize_net_data_values(struct oonf_viewer_template *template,
  */
 static void
 _initialize_neigh_data_values(struct oonf_viewer_template *template,
-    struct isonumber_str *dst, struct oonf_layer2_data *data) {
+    struct oonf_layer2_data *data) {
   size_t i;
 
-  memset(dst, 0, sizeof(*dst) * OONF_LAYER2_NEIGH_COUNT);
+  memset(_value_neigh_data, 0, sizeof(_value_neigh_data));
 
   for (i=0; i<OONF_LAYER2_NEIGH_COUNT; i++) {
     if (oonf_layer2_has_value(&data[i])) {
-      isonumber_from_s64(&dst[i], oonf_layer2_get_value(&data[i]),
+      isonumber_from_s64(&_value_neigh_data[i],
+          oonf_layer2_get_value(&data[i]),
           oonf_layer2_get_neigh_metadata(i)->unit,
           oonf_layer2_get_neigh_metadata(i)->fraction,
           oonf_layer2_get_neigh_metadata(i)->binary,
@@ -399,19 +479,19 @@ _initialize_neigh_data_values(struct oonf_viewer_template *template,
 }
 
 /**
- * Initialize the value buffers for a layer2 neighbor
- * @param neigh layer2 neighbor
+ * Initialize the network origin buffers for an array of layer2 data objects
+ * @param data array of data objects
  */
 static void
-_initialize_neighbor_values(struct oonf_layer2_neigh *neigh) {
-  netaddr_to_string(&_value_neigh_addr, &neigh->addr);
+_initialize_neigh_origin_values(struct oonf_layer2_data *data) {
+  size_t i;
 
-  if (neigh->last_seen) {
-    oonf_clock_toIntervalString(&_value_neigh_lastseen,
-        -oonf_clock_get_relative(neigh->last_seen));
-  }
-  else {
-    _value_neigh_lastseen.buf[0] = 0;
+  memset(_value_neigh_origin, 0, sizeof(_value_neigh_origin));
+
+  for (i=0; i<OONF_LAYER2_NEIGH_COUNT; i++) {
+    if (oonf_layer2_has_value(&data[i])) {
+      strscpy(_value_neigh_origin[i], oonf_layer2_get_origin(&data[i])->name, IF_NAMESIZE);
+    }
   }
 }
 
@@ -422,6 +502,7 @@ _initialize_neighbor_values(struct oonf_layer2_neigh *neigh) {
 static void
 _initialize_destination_values(struct oonf_layer2_destination *l2dst) {
   netaddr_to_string(&_value_dst_addr, &l2dst->destination);
+  strscpy(_value_dst_origin, l2dst->origin->name, IF_NAMESIZE);
 }
 
 /**
@@ -434,8 +515,9 @@ _cb_create_text_interface(struct oonf_viewer_template *template) {
   struct oonf_layer2_net *net;
 
   avl_for_each_element(oonf_layer2_get_network_tree(), net, _node) {
-    _initialize_interface_values(net);
-    _initialize_net_data_values(template, _value_if_data, net->data);
+    _initialize_if_values(net);
+    _initialize_if_data_values(template, net->data);
+    _initialize_if_origin_values(net->data);
 
     /* generate template output */
     oonf_viewer_output_print_line(template);
@@ -454,11 +536,12 @@ _cb_create_text_neighbor(struct oonf_viewer_template *template) {
   struct oonf_layer2_net *net;
 
   avl_for_each_element(oonf_layer2_get_network_tree(), net, _node) {
-    _initialize_interface_values(net);
+    _initialize_if_values(net);
 
     avl_for_each_element(&net->neighbors, neigh, _node) {
-      _initialize_neighbor_values(neigh);
-      _initialize_neigh_data_values(template, _value_neigh_data, neigh->data);
+      _initialize_neigh_values(neigh);
+      _initialize_neigh_data_values(template, neigh->data);
+      _initialize_neigh_origin_values(neigh->data);
 
       /* generate template output */
       oonf_viewer_output_print_line(template);
@@ -478,8 +561,9 @@ _cb_create_text_default(struct oonf_viewer_template *template) {
   struct oonf_layer2_net *net;
 
   avl_for_each_element(oonf_layer2_get_network_tree(), net, _node) {
-    _initialize_interface_values(net);
-    _initialize_neigh_data_values(template, _value_neigh_data, net->neighdata);
+    _initialize_if_values(net);
+    _initialize_neigh_data_values(template, net->neighdata);
+    _initialize_neigh_origin_values(net->neighdata);
 
     /* generate template output */
     oonf_viewer_output_print_line(template);
@@ -499,10 +583,10 @@ _cb_create_text_dst(struct oonf_viewer_template *template) {
   struct oonf_layer2_net *net;
 
   avl_for_each_element(oonf_layer2_get_network_tree(), net, _node) {
-    _initialize_interface_values(net);
+    _initialize_if_values(net);
 
     avl_for_each_element(&net->neighbors, neigh, _node) {
-      _initialize_neighbor_values(neigh);
+      _initialize_neigh_values(neigh);
 
       avl_for_each_element(&neigh->destinations, l2dst, _node) {
         _initialize_destination_values(l2dst);
index 3fdad89..d7d1bb7 100644 (file)
@@ -51,8 +51,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 "link_config/link_config.h"
 
 static void _early_cfg_init(void);
 static int _init(void);
 static void _cleanup(void);
+
+static void _cb_update_link_config(void *);
+static void _cb_delayed_config(struct oonf_timer_instance *);
+
 static int _cb_validate_linkdata(const struct cfg_schema_entry *entry,
     const char *section_name, const char *value, struct autobuf *out);
 static void _parse_strarray(struct strarray *array, const char *ifname,
@@ -103,8 +108,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,
@@ -118,7 +123,41 @@ static struct oonf_subsystem _oonf_link_config_subsystem = {
 };
 DECLARE_OONF_PLUGIN(_oonf_link_config_subsystem);
 
-static uint32_t _l2_origin_current, _l2_origin_old;
+/* originator for smooth set/remove of configured layer2 values */
+static struct oonf_layer2_origin _l2_origin_current = {
+  .name = "link config updated",
+  .priority = OONF_LAYER2_ORIGIN_CONFIGURED,
+};
+static struct oonf_layer2_origin _l2_origin_old = {
+  .name = "link config",
+  .priority = OONF_LAYER2_ORIGIN_CONFIGURED,
+};
+
+/* listener for removal of layer2 data */
+static struct oonf_class_extension _l2net_listener = {
+  .ext_name = "link config listener",
+  .class_name = LAYER2_CLASS_NETWORK,
+
+  .cb_remove = _cb_update_link_config,
+  .cb_change = _cb_update_link_config,
+};
+static struct oonf_class_extension _l2neigh_listener = {
+  .ext_name = "link config listener",
+  .class_name = LAYER2_CLASS_NEIGHBOR,
+
+  .cb_remove = _cb_update_link_config,
+  .cb_change = _cb_update_link_config,
+};
+
+/* timer for lazy updates */
+static struct oonf_timer_class _lazy_update_class = {
+  .name = "lazy link config",
+  .callback = _cb_delayed_config,
+};
+
+static struct oonf_timer_instance _lazy_update_instance = {
+  .class = &_lazy_update_class,
+};
 
 static void
 _early_cfg_init(void) {
@@ -139,8 +178,14 @@ _early_cfg_init(void) {
  */
 static int
 _init(void) {
-  _l2_origin_current = oonf_layer2_register_origin();
-  _l2_origin_old = oonf_layer2_register_origin();
+  oonf_layer2_add_origin(&_l2_origin_current);
+  oonf_layer2_add_origin(&_l2_origin_old);
+
+  oonf_class_extension_add(&_l2net_listener);
+  oonf_class_extension_add(&_l2neigh_listener);
+
+  oonf_timer_add(&_lazy_update_class);
+
   return 0;
 }
 
@@ -149,8 +194,39 @@ _init(void) {
  */
 static void
 _cleanup(void) {
-  oonf_layer2_cleanup_origin(_l2_origin_current);
-  oonf_layer2_cleanup_origin(_l2_origin_old);
+  oonf_timer_stop(&_lazy_update_instance);
+  oonf_timer_remove(&_lazy_update_class);
+
+  oonf_class_extension_remove(&_l2net_listener);
+  oonf_class_extension_remove(&_l2neigh_listener);
+
+  oonf_layer2_remove_origin(&_l2_origin_current);
+  oonf_layer2_remove_origin(&_l2_origin_old);
+}
+
+/**
+ * Listener for removal of layer2 database entries. Will trigger
+ * a delayed reset of this plugins configured data
+ * @param ptr unused
+ */
+static void
+_cb_update_link_config(void *ptr __attribute__((unused))) {
+  if (!oonf_timer_is_active(&_lazy_update_instance)) {
+    OONF_DEBUG(LOG_LINK_CONFIG, "Trigger lazy update");
+    oonf_timer_set(&_lazy_update_instance,
+        OONF_LINK_CONFIG_REWRITE_DELAY);
+  }
+}
+
+/**
+ * Callback for delayed update.
+ * @param timer unused
+ */
+static void
+_cb_delayed_config(struct oonf_timer_instance *timer __attribute__((unused))) {
+  /* re-read the configuration */
+  OONF_DEBUG(LOG_LINK_CONFIG, "Update configuration settings");
+  _cb_config_changed();
 }
 
 /**
@@ -194,29 +270,6 @@ _cb_validate_linkdata(const struct cfg_schema_entry *entry,
   return 0;
 }
 
-/**
- * Overwrite a layer-2 value that is either not set or was
- * set by this plugin.
- * @param data pointer to layer2 data
- * @param value new value
- * @return -1 if value was not overwritten, 0 otherwise
- */
-static int
-_set_l2value(struct oonf_layer2_data *data, int64_t value) {
-  uint32_t origin;
-
-  if (oonf_layer2_has_value(data)) {
-    origin = oonf_layer2_get_origin(data);
-
-    if (origin != 0 && origin != _l2_origin_current && origin != _l2_origin_old) {
-      return -1;
-    }
-  }
-
-  oonf_layer2_set_value(data, _l2_origin_current, value);
-  return 0;
-}
-
 /**
  * Parse user input and add the corresponding database entries
  * @param array pointer to string array
@@ -250,7 +303,7 @@ _parse_strarray(struct strarray *array, const char *ifname,
 
     if (ptr == NULL) {
       /* add network wide data entry */
-      if (!_set_l2value(&l2net->neighdata[idx], value)) {
+      if (!oonf_layer2_set_value(&l2net->neighdata[idx], &_l2_origin_current, value)) {
         OONF_INFO(LOG_LINK_CONFIG, "if-wide %s for %s: %s",
             oonf_layer2_get_neigh_metadata(idx)->key, ifname, hbuf.buf);
       }
@@ -269,7 +322,7 @@ _parse_strarray(struct strarray *array, const char *ifname,
         continue;
       }
 
-      if (!_set_l2value(&l2neigh->data[idx], value)) {
+      if (!oonf_layer2_set_value(&l2neigh->data[idx], &_l2_origin_current, value)) {
         OONF_INFO(LOG_LINK_CONFIG, "%s to neighbor %s on %s: %s",
             oonf_layer2_get_neigh_metadata(idx)->key, nbuf.buf, ifname, hbuf.buf);
       }
@@ -287,6 +340,8 @@ _cb_config_changed(void) {
   struct oonf_layer2_neigh *l2neigh, *l2neigh_it;
   struct oonf_layer2_net *l2net;
   struct cfg_entry *entry;
+  char ifbuf[IF_NAMESIZE];
+  const char *ifname;
   size_t idx;
   bool commit;
 
@@ -302,32 +357,32 @@ _cb_config_changed(void) {
     }
   }
 
-  l2net = oonf_layer2_net_get(_link_config_section.section_name);
+  ifname = cfg_get_phy_if(ifbuf, _link_config_section.section_name);
+  l2net = oonf_layer2_net_get(ifname);
   if (l2net) {
     /* remove old entries and trigger remove events */
-    oonf_layer2_net_cleanup(l2net, _l2_origin_old);
+    oonf_layer2_net_cleanup(l2net, &_l2_origin_old, true);
 
     commit = false;
     /* detect changes and relabel the origin */
     avl_for_each_element_safe(&l2net->neighbors, l2neigh, _node, l2neigh_it) {
       for (idx = 0; idx < OONF_LAYER2_NEIGH_COUNT; idx++) {
-        if (oonf_layer2_get_origin(&l2neigh->data[idx]) == _l2_origin_current) {
-          oonf_layer2_set_origin(&l2neigh->data[idx], _l2_origin_old);
+        if (oonf_layer2_get_origin(&l2neigh->data[idx]) == &_l2_origin_current) {
+          oonf_layer2_set_origin(&l2neigh->data[idx], &_l2_origin_old);
           commit = true;
         }
       }
-    }
-
-    if (commit) {
-      /* trigger change event */
-     oonf_layer2_neigh_commit(l2neigh);
+      if (commit) {
+        /* trigger change event */
+       oonf_layer2_neigh_commit(l2neigh);
+      }
     }
 
     commit = false;
     /* detect changes and relabel the origin */
     for (idx = 0; idx < OONF_LAYER2_NET_COUNT; idx++) {
-      if (oonf_layer2_get_origin(&l2net->neighdata[idx]) == _l2_origin_current) {
-        oonf_layer2_set_origin(&l2net->neighdata[idx], _l2_origin_old);
+      if (oonf_layer2_get_origin(&l2net->neighdata[idx]) == &_l2_origin_current) {
+        oonf_layer2_set_origin(&l2net->neighdata[idx], &_l2_origin_old);
         commit = true;
       }
     }
index e8ec94f..7813b78 100644 (file)
@@ -49,4 +49,8 @@
 /*! subsystem identifier */
 #define OONF_LINK_CONFIG_SUBSYSTEM "link_config"
 
+enum {
+  OONF_LINK_CONFIG_REWRITE_DELAY = 1000,
+};
+
 #endif /* OONF_LINKCONFIG_H_ */
index b340ef2..6757bfb 100644 (file)
@@ -97,12 +97,12 @@ static uint64_t _get_bandwidth(uint32_t width);
 void
 nl80211_send_get_interface(struct os_system_netlink *nl,
     struct nlmsghdr *nl_msg, struct genlmsghdr *hdr, struct nl80211_if *interf) {
-  int if_index = nl80211_get_if_index(interf);
+  int if_index = nl80211_get_if_baseindex(interf);
 
   hdr->cmd = NL80211_CMD_GET_INTERFACE;
 
   /* add interface index to the request */
-  os_system_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
+  os_system_linux_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
       &if_index, sizeof(if_index));
 }
 
@@ -127,7 +127,7 @@ nl80211_process_get_interface_result(struct nl80211_if *interf,
     return;
   }
 
-  interf->phy_if = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]);
+  interf->wifi_phy_if = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]);
 
   if (tb_msg[NL80211_ATTR_SSID]) {
     char ssid[33];
index a87759e..4b5454c 100644 (file)
 void
 nl80211_send_get_mpp(struct os_system_netlink *nl, struct nlmsghdr *nl_msg,
     struct genlmsghdr *hdr, struct nl80211_if *interf) {
-  int if_index = nl80211_get_if_index(interf);
+  int if_index = nl80211_get_if_baseindex(interf);
 
   hdr->cmd = NL80211_CMD_GET_MPP;
   nl_msg->nlmsg_flags |= NLM_F_DUMP;
 
   /* add interface index to the request */
-  os_system_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
+  os_system_linux_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
       &if_index, sizeof(if_index));
 }
 
@@ -128,7 +128,7 @@ nl80211_process_get_mpp_result(struct nl80211_if *interf,
   nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
       genlmsg_attrlen(gnlh, 0), NULL);
 
-  if (nl80211_get_if_index(interf) != nla_get_u32(tb[NL80211_ATTR_IFINDEX])) {
+  if (nl80211_get_if_baseindex(interf) != nla_get_u32(tb[NL80211_ATTR_IFINDEX])) {
     /* wrong interface ? */
     return;
   }
index fef5e16..b37d06f 100644 (file)
@@ -101,13 +101,13 @@ static int64_t _get_bitrate(struct nlattr *bitrate_attr);
 void
 nl80211_send_get_station_dump(struct os_system_netlink *nl,
     struct nlmsghdr *nl_msg, struct genlmsghdr *hdr, struct nl80211_if *interf) {
-  int if_index = nl80211_get_if_index(interf);
+  int if_index = nl80211_get_if_baseindex(interf);
 
   hdr->cmd = NL80211_CMD_GET_STATION;
   nl_msg->nlmsg_flags |= NLM_F_DUMP;
 
   /* add interface index to the request */
-  os_system_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
+  os_system_linux_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
       &if_index, sizeof(if_index));
 }
 
@@ -159,7 +159,7 @@ nl80211_process_get_station_dump_result(struct nl80211_if *interf,
     return;
   }
 
-  if (nl80211_get_if_index(interf) != nla_get_u32(tb[NL80211_ATTR_IFINDEX])) {
+  if (nl80211_get_if_baseindex(interf) != nla_get_u32(tb[NL80211_ATTR_IFINDEX])) {
     /* wrong interface */
     return;
   }
index 80afee7..ad36ad8 100644 (file)
 void
 nl80211_send_get_survey(struct os_system_netlink *nl, struct nlmsghdr *nl_msg,
     struct genlmsghdr *hdr, struct nl80211_if *interf) {
-  int if_index = nl80211_get_if_index(interf);
+  int if_index = nl80211_get_if_baseindex(interf);
 
   hdr->cmd = NL80211_CMD_GET_SURVEY;
   nl_msg->nlmsg_flags |= NLM_F_DUMP;
 
   /* add interface index to the request */
-  os_system_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
+  os_system_linux_netlink_addreq(nl, nl_msg, NL80211_ATTR_IFINDEX,
       &if_index, sizeof(if_index));
 }
 
@@ -126,7 +126,7 @@ nl80211_process_get_survey_result(struct nl80211_if *interf, struct nlmsghdr *hd
   nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
       genlmsg_attrlen(gnlh, 0), NULL);
 
-  if (nl80211_get_if_index(interf) != nla_get_u32(tb[NL80211_ATTR_IFINDEX])) {
+  if (nl80211_get_if_baseindex(interf) != nla_get_u32(tb[NL80211_ATTR_IFINDEX])) {
     /* wrong interface ? */
     return;
   }
index f5720a0..a06b0b8 100644 (file)
@@ -175,14 +175,14 @@ nl80211_send_get_wiphy(struct os_system_netlink *nl,
   nl_msg->nlmsg_flags |= NLM_F_DUMP;
 
   /* add "split wiphy dump" flag */
-  os_system_netlink_addreq(nl, nl_msg, NL80211_ATTR_SPLIT_WIPHY_DUMP,
+  os_system_linux_netlink_addreq(nl, nl_msg, NL80211_ATTR_SPLIT_WIPHY_DUMP,
       NULL, 0);
 
   /* add interface index to the request */
-  os_system_netlink_addreq(nl, nl_msg, NL80211_ATTR_WIPHY,
-      &interf->phy_if, sizeof(interf->phy_if));
+  os_system_linux_netlink_addreq(nl, nl_msg, NL80211_ATTR_WIPHY,
+      &interf->wifi_phy_if, sizeof(interf->wifi_phy_if));
 
-  OONF_DEBUG(LOG_NL80211, "Send GET_WIPHY to phydev %d", interf->phy_if);
+  OONF_DEBUG(LOG_NL80211, "Send GET_WIPHY to phydev %d", interf->wifi_phy_if);
 }
 
 /**
@@ -206,7 +206,7 @@ nl80211_process_get_wiphy_result(struct nl80211_if *interf,
       genlmsg_attrlen(gnlh, 0), NULL);
 
   if (tb_msg[NL80211_ATTR_WIPHY]) {
-    interf->phy_if = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]);
+    interf->wifi_phy_if = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]);
   }
   else {
     return;
@@ -251,14 +251,18 @@ nl80211_process_get_wiphy_result(struct nl80211_if *interf,
  */
 void
 nl80211_finalize_get_wiphy(struct nl80211_if *interf) {
-  OONF_DEBUG(LOG_NL80211, "Maximum rx rate for %s: %"PRId64,
-      interf->name, interf->max_rx);
-  OONF_DEBUG(LOG_NL80211, "Maximum tx rate for %s: %"PRId64,
-      interf->name, interf->max_tx);
-  interf->ifdata_changed |= nl80211_change_l2net_neighbor_default(
-      interf->l2net, OONF_LAYER2_NEIGH_RX_MAX_BITRATE, interf->max_rx);
-  interf->ifdata_changed |= nl80211_change_l2net_neighbor_default(
-      interf->l2net, OONF_LAYER2_NEIGH_TX_MAX_BITRATE, interf->max_tx);
+  if (interf->max_rx) {
+    OONF_DEBUG(LOG_NL80211, "Maximum rx rate for %s: %"PRId64,
+        interf->name, interf->max_rx);
+    interf->ifdata_changed |= nl80211_change_l2net_neighbor_default(
+        interf->l2net, OONF_LAYER2_NEIGH_RX_MAX_BITRATE, interf->max_rx);
+  }
+  if (interf->max_tx) {
+    OONF_DEBUG(LOG_NL80211, "Maximum tx rate for %s: %"PRId64,
+        interf->name, interf->max_tx);
+    interf->ifdata_changed |= nl80211_change_l2net_neighbor_default(
+        interf->l2net, OONF_LAYER2_NEIGH_TX_MAX_BITRATE, interf->max_tx);
+  }
 }
 
 /**
index ec31775..ac87819 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"
@@ -185,7 +185,7 @@ static void _nl80211_if_remove(struct nl80211_if *);
 static void _cb_config_changed(void);
 static void _cb_if_config_changed(void);
 
-static void _cb_transmission_event(void *);
+static void _cb_transmission_event(struct oonf_timer_instance *);
 static void _trigger_next_netlink_query(void);
 
 static void _cb_nl_message(struct nlmsghdr *hdr);
@@ -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,
 };
 
@@ -266,7 +266,16 @@ static uint32_t _nl80211_id = 0;
 static uint32_t _nl80211_multicast_group = 0;
 
 /* layer2 metadata */
-static uint32_t _layer2_origin, _layer2_old_origin;
+static struct oonf_layer2_origin _layer2_updated_origin = {
+  .name = "nl80211 updated",
+  .proactive = true,
+  .priority = OONF_LAYER2_ORIGIN_RELIABLE,
+};
+static struct oonf_layer2_origin _layer2_data_origin = {
+  .name = "nl80211",
+  .proactive = true,
+  .priority = OONF_LAYER2_ORIGIN_RELIABLE,
+};
 
 /* current query data */
 static struct nl80211_if *_current_query_if = NULL;
@@ -303,7 +312,7 @@ _early_cfg_init(void) {
  */
 static int
 _init(void) {
-  if (os_system_netlink_add(&_netlink_handler, NETLINK_GENERIC)) {
+  if (os_system_linux_netlink_add(&_netlink_handler, NETLINK_GENERIC)) {
     return -1;
   }
 
@@ -312,8 +321,8 @@ _init(void) {
   avl_init(&_nl80211_if_tree, avl_comp_strcasecmp, false);
 
   /* get layer2 origin */
-  _layer2_origin = oonf_layer2_register_origin();
-  _layer2_old_origin = oonf_layer2_register_origin();
+  oonf_layer2_add_origin(&_layer2_updated_origin);
+  oonf_layer2_add_origin(&_layer2_data_origin);
 
   oonf_timer_add(&_transmission_timer_info);
   return 0;
@@ -328,11 +337,12 @@ _cleanup(void) {
   avl_for_each_element_safe(&_nl80211_if_tree, interf, _node, it_if) {
     _nl80211_if_remove(interf);
   }
-  oonf_layer2_cleanup_origin(_layer2_origin);
+  oonf_layer2_remove_origin(&_layer2_updated_origin);
+  oonf_layer2_remove_origin(&_layer2_data_origin);
 
   oonf_timer_stop(&_transmission_timer);
   oonf_timer_remove(&_transmission_timer_info);
-  os_system_netlink_remove(&_netlink_handler);
+  os_system_linux_netlink_remove(&_netlink_handler);
 }
 
 /**
@@ -345,9 +355,9 @@ struct oonf_layer2_destination *
 nl80211_add_dst(struct oonf_layer2_neigh *l2neigh, const struct netaddr *dstmac) {
   struct oonf_layer2_destination *dst;
 
-  dst = oonf_layer2_destination_add(l2neigh, dstmac, _layer2_origin);
-  if (dst->origin == _layer2_old_origin) {
-    dst->origin = _layer2_origin;
+  dst = oonf_layer2_destination_add(l2neigh, dstmac, &_layer2_updated_origin);
+  if (dst->origin == &_layer2_data_origin) {
+    dst->origin = &_layer2_updated_origin;
   }
   return dst;
 }
@@ -362,7 +372,7 @@ nl80211_add_dst(struct oonf_layer2_neigh *l2neigh, const struct netaddr *dstmac)
 bool
 nl80211_change_l2net_data(struct oonf_layer2_net *l2net,
     enum oonf_layer2_network_index idx, uint64_t value) {
-  return oonf_layer2_change_value(&l2net->data[idx], _layer2_origin, value);
+  return oonf_layer2_change_value(&l2net->data[idx], &_layer2_updated_origin, value);
 }
 
 /**
@@ -375,7 +385,7 @@ nl80211_change_l2net_data(struct oonf_layer2_net *l2net,
 bool
 nl80211_change_l2net_neighbor_default(struct oonf_layer2_net *l2net,
     enum oonf_layer2_neighbor_index idx, uint64_t value) {
-  return oonf_layer2_change_value(&l2net->neighdata[idx], _layer2_origin, value);
+  return oonf_layer2_change_value(&l2net->neighdata[idx], &_layer2_updated_origin, value);
 }
 
 /**
@@ -385,7 +395,7 @@ nl80211_change_l2net_neighbor_default(struct oonf_layer2_net *l2net,
  */
 void
 nl80211_cleanup_l2neigh_data(struct oonf_layer2_neigh *l2neigh) {
-  oonf_layer2_neigh_cleanup(l2neigh, _layer2_old_origin);
+  oonf_layer2_neigh_cleanup(l2neigh, &_layer2_data_origin);
 }
 
 /**
@@ -398,7 +408,7 @@ nl80211_cleanup_l2neigh_data(struct oonf_layer2_neigh *l2neigh) {
 bool
 nl80211_change_l2neigh_data(struct oonf_layer2_neigh *l2neigh,
     enum oonf_layer2_neighbor_index idx, uint64_t value) {
-  return oonf_layer2_change_value(&l2neigh->data[idx], _layer2_origin, value);
+  return oonf_layer2_change_value(&l2neigh->data[idx], &_layer2_updated_origin, value);
 }
 
 /**
@@ -449,14 +459,15 @@ _nl80211_if_add(const char *name) {
 
   /* initialize interface listener */
   interf->if_listener.name = interf->name;
-  if (oonf_interface_add_listener(&interf->if_listener)) {
-    oonf_layer2_net_remove(interf->l2net, _layer2_origin);
+  if (!os_interface_add(&interf->if_listener)) {
+    oonf_layer2_net_remove(interf->l2net, &_layer2_data_origin);
+    oonf_layer2_net_remove(interf->l2net, &_layer2_updated_origin);
     oonf_class_free(&_nl80211_if_class, interf);
     return NULL;
   }
 
-  /* initialize physical interface */
-  interf->phy_if = -1;
+  /* initialize interface */
+  interf->wifi_phy_if = -1;
 
   OONF_DEBUG(LOG_NL80211, "Add if %s", name);
   avl_insert(&_nl80211_if_tree, &interf->_node);
@@ -470,7 +481,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);
 }
 
@@ -480,16 +491,19 @@ _nl80211_if_remove(struct nl80211_if *interf) {
 static void
 _cb_if_config_changed(void) {
   struct nl80211_if *interf;
+  const char *ifname;
+  char ifbuf[IF_NAMESIZE];
 
+  ifname = cfg_get_phy_if(ifbuf, _if_section.section_name);
   if (_if_section.pre == NULL) {
-    interf = _nl80211_if_add(_if_section.section_name);
+    interf = _nl80211_if_add(ifname);
     if (interf) {
       interf->_if_section = true;
     }
   }
 
   if (_if_section.post == NULL) {
-    interf = _nl80211_if_get(_if_section.section_name);
+    interf = _nl80211_if_get(ifname);
     if (interf) {
       interf->_if_section = false;
       if (!interf->_nl80211_section) {
@@ -501,10 +515,10 @@ _cb_if_config_changed(void) {
 
 /**
  * Transmit the next netlink command to nl80211
- * @param ptr unused
+ * @param ptr timer instance that fired
  */
 static void
-_cb_transmission_event(void *ptr __attribute__((unused))) {
+_cb_transmission_event(struct oonf_timer_instance *ptr __attribute__((unused))) {
   if (!_current_query_in_progress) {
     _trigger_next_netlink_query();
   }
@@ -547,7 +561,7 @@ _send_netlink_message(struct nl80211_if *interf, enum _if_query query) {
     _if_query_ops[query].send(&_netlink_handler, _nl_msg, hdr, interf);
   }
 
-  os_system_netlink_send(&_netlink_handler, _nl_msg);
+  os_system_linux_netlink_send(&_netlink_handler, _nl_msg);
 }
 
 /**
@@ -563,16 +577,10 @@ _get_next_query(void) {
 
   /* no query left to do? start again at the first */
   if (!_current_query_if) {
-    int id;
     /* start with first interface and query */
     _current_query_if = avl_first_element(&_nl80211_if_tree, _current_query_if, _node);
     _current_query_number = QUERY_START;
     _current_query_in_progress = true;
-
-    /* switch nl80211 layer2-origin's */
-    id = _layer2_origin;
-    _layer2_origin = _layer2_old_origin;
-    _layer2_old_origin = id;
   }
   else {
     /* next query */
@@ -581,7 +589,9 @@ _get_next_query(void) {
     if (_current_query_number == QUERY_END) {
       /* commit interface data */
       if (_current_query_if->ifdata_changed) {
-        oonf_layer2_net_remove(_current_query_if->l2net, _layer2_old_origin);
+        oonf_layer2_net_cleanup(_current_query_if->l2net, &_layer2_data_origin, true);
+        oonf_layer2_net_relabel(_current_query_if->l2net,
+            &_layer2_data_origin, &_layer2_updated_origin);
         oonf_layer2_net_commit(_current_query_if->l2net);
         _current_query_if->ifdata_changed = false;
       }
index 84106c8..ceb5cad 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,13 +62,13 @@ 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;
 
-  /*! physical interface id, might be different because of VLANs */
-  int phy_if;
+  /*! physical interface index */
+  int wifi_phy_if;
 
   /*! maximum tx rate */
   uint64_t max_tx;
@@ -107,8 +107,8 @@ bool nl80211_change_l2neigh_data(struct oonf_layer2_neigh *l2neigh,
  * @returns nl80211 interface index
  */
 static INLINE unsigned
-nl80211_get_if_index(struct nl80211_if *interf) {
-  return interf->if_listener.interface->data.index;
+nl80211_get_if_baseindex(struct nl80211_if *interf) {
+  return interf->if_listener.data->base_index;
 }
 
 #endif /* NL80211_LISTENER_H_ */
index cdc207f..b2b669b 100644 (file)
@@ -622,7 +622,7 @@ _cb_handle_route(struct oonf_telnet_data *data) {
   struct os_route route;
   int result;
 
-  memcpy(&route, os_routing_get_wildcard_route(), sizeof(route));
+  os_routing_init_wildcard_route(&route);
 
   if ((next = str_hasnextword(data->parameter, "add")) != NULL) {
     add = true;
index 33707f0..071e8a4 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"
 
 /* constants and definitions */
 #define LOG_AUTO_LL4 _olsrv2_auto_ll4_subsystem.logging
 
-/**
- * Configuration for auto-ll4 plugin
- */
-struct _config {
-  /*! delay until plugin starts generating interface addresses */
-  uint64_t startup_delay;
-};
-
 /**
  * NHDP interface class extension of autoll4 plugin
  */
@@ -83,14 +74,20 @@ struct _nhdp_if_autoll4 {
   /*! timer until next update of autogenerated ip */
   struct oonf_timer_instance update_timer;
 
-  /*! true if interface LL4 was generated by this plugin */
+  /*! back pointer to NHDP interface */
+  struct nhdp_interface *nhdp_if;
+
+  /*! true if autoll4 is active for this interface */
   bool active;
 
+  /*! delay until plugin starts generating interface addresses */
+  uint64_t startup_delay;
+
   /*! true if current LL4 was generated by the plugin */
   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;
@@ -103,10 +100,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_update_timer(void *);
+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);
@@ -121,13 +118,14 @@ static bool _nhdp_if_has_collision(
 static void _cb_ifaddr_change(void *);
 static void _cb_laddr_change(void *);
 static void _cb_2hop_change(void *);
-static void _cb_ll4_cfg_changed(void);
 static void _cb_if_cfg_changed(void);
 
 /* plugin declaration */
 static struct cfg_schema_entry _interface_entries[] = {
   CFG_MAP_BOOL(_nhdp_if_autoll4, active, "auto_ll4", "true",
       "Controls autogeneration of IPv4 linklocal IPs on interface."),
+  CFG_MAP_CLOCK(_nhdp_if_autoll4, startup_delay, "autoll4_startup_delay", "10",
+      "Startup time until first auto-configured IPv4 linklocal should be selected."),
 };
 
 static struct cfg_schema_section _interface_section = {
@@ -138,24 +136,9 @@ static struct cfg_schema_section _interface_section = {
   .entry_count = ARRAYSIZE(_interface_entries),
 };
 
-static struct cfg_schema_entry _auto_ll4_entries[] = {
-  CFG_MAP_CLOCK(_config, startup_delay, "startup", "10",
-      "Startup time until first auto-configured IPv4 linklocal should be selected."),
-};
-
-static struct cfg_schema_section _auto_ll4_section = {
-  .type = OONF_AUTO_LL4_SUBSYSTEM,
-  .mode = CFG_SSMODE_UNNAMED,
-  .cb_delta_handler = _cb_ll4_cfg_changed,
-  .entries = _auto_ll4_entries,
-  .entry_count = ARRAYSIZE(_auto_ll4_entries),
-  .next_section = &_interface_section,
-};
-
 static const char *_dependencies[] = {
   OONF_CLASS_SUBSYSTEM,
   OONF_TIMER_SUBSYSTEM,
-  OONF_INTERFACE_SUBSYSTEM,
   OONF_OS_INTERFACE_SUBSYSTEM,
   OONF_NHDP_SUBSYSTEM,
 };
@@ -166,7 +149,7 @@ static struct oonf_subsystem _olsrv2_auto_ll4_subsystem = {
   .descr = "OLSRv2 Automatic IPv4 Linklayer IP generation plugin",
   .author = "Henning Rogge",
 
-  .cfg_section = &_auto_ll4_section,
+  .cfg_section = &_interface_section,
 
   .init = _init,
   .cleanup = _cleanup,
@@ -218,9 +201,6 @@ static struct oonf_class_extension _nhdp_2hop_listener = {
   .cb_remove = _cb_2hop_change,
 };
 
-/* global variables */
-static uint64_t _ll4_startup_delay = 10*1000;
-
 /**
  * Initialize plugin
  * @return -1 if an error happened, 0 otherwise
@@ -244,11 +224,12 @@ _init(void) {
  */
 static void
 _initiate_shutdown(void) {
-  struct nhdp_interface *nhdp_if;
+  struct nhdp_interface *nhdp_if, *nhdp_if_it;
 
-  avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
+  /* cleanup plugin specific data for interfaces that still exist */
+  avl_for_each_element_safe(nhdp_interface_get_tree(), nhdp_if, _node, nhdp_if_it) {
     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);
@@ -276,16 +257,15 @@ _cb_add_nhdp_interface(void *ptr) {
 
   /* get auto linklayer extension */
   auto_ll4 = oonf_class_get_extension(&_nhdp_if_extenstion, nhdp_if);
+  auto_ll4->nhdp_if = nhdp_if;
 
   /* 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.scope = OS_ADDR_SCOPE_LINK;
 
+
   /* activate update_timer delay timer */
   auto_ll4->update_timer.class = &_startup_timer_info;
-  auto_ll4->update_timer.cb_context = nhdp_if;
-  oonf_timer_set(&auto_ll4->update_timer, _ll4_startup_delay);
 }
 
 /**
@@ -306,10 +286,13 @@ _cb_remove_nhdp_interface(void *ptr) {
 
   /* cleanup address if necessary */
   auto_ll4->active = false;
-  _cb_update_timer(nhdp_if);
+  _cb_update_timer(&auto_ll4->update_timer);
 
   /* stop update timer */
   oonf_timer_stop(&auto_ll4->update_timer);
+
+  /* cleanup pointer to nhdp interface */
+  auto_ll4->nhdp_if = NULL;
 }
 
 /**
@@ -319,7 +302,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;
@@ -363,6 +346,11 @@ _cb_ifaddr_change(void *ptr) {
   /* get auto linklayer extension */
   auto_ll4 = oonf_class_get_extension(&_nhdp_if_extenstion, nhdp_if);
 
+  if (!auto_ll4->nhdp_if) {
+    /* Interface already cleaned up */
+    return;
+  }
+
   if (!oonf_timer_is_active(&auto_ll4->update_timer)) {
     /* request delayed address check */
     oonf_timer_set(&auto_ll4->update_timer, 1);
@@ -429,12 +417,12 @@ _cb_2hop_change(void *ptr) {
 /**
  * Callback triggered when the plugin should check if the autoconfigured
  * address is still okay.
- * @param ptr pointer to NHDP interface
+ * @param ptr timer instance that fired
  */
 static void
-_cb_update_timer(void *ptr) {
-  struct nhdp_interface *nhdp_if = ptr;
-  struct os_interface_data *ifdata;
+_cb_update_timer(struct oonf_timer_instance *ptr) {
+  struct nhdp_interface *nhdp_if;
+  struct os_interface *os_if;
   struct _nhdp_if_autoll4 *auto_ll4;
   struct netaddr current_ll4;
   int count;
@@ -444,21 +432,26 @@ _cb_update_timer(void *ptr) {
   struct netaddr_str nbuf;
 #endif
 
+  auto_ll4 = container_of(ptr, struct _nhdp_if_autoll4, update_timer);
+  nhdp_if = auto_ll4->nhdp_if;
+
+  if (!nhdp_if) {
+    return;
+  }
+
   /* get pointer to interface data */
-  ifdata = &(nhdp_interface_get_coreif(nhdp_if)->data);
+  os_if = nhdp_interface_get_if_listener(nhdp_if)->data;
+  auto_ll4->os_addr.if_index = os_if->index;
 
   /* ignore loopback */
-  if (ifdata->loopback || !ifdata->up) {
+  if (os_if->flags.loopback || !os_if->flags.up) {
     OONF_DEBUG(LOG_AUTO_LL4, "Ignore interface %s: its loopback or down",
-        ifdata->name);
+        os_if->name);
     return;
   }
 
-  /* get auto linklayer extension */
-  auto_ll4 = oonf_class_get_extension(&_nhdp_if_extenstion, nhdp_if);
-
   /* 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) {
@@ -468,7 +461,7 @@ _cb_update_timer(void *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;
   }
 
@@ -479,7 +472,7 @@ _cb_update_timer(void *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;
   }
 
@@ -490,14 +483,14 @@ _cb_update_timer(void *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;
     }
 
@@ -507,7 +500,7 @@ _cb_update_timer(void *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)) {
@@ -524,7 +517,7 @@ _cb_update_timer(void *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;
   }
 
@@ -582,14 +575,13 @@ _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;
+  struct netaddr_str nbuf1, nbuf2;
 #endif
 
   /* reset counter */
@@ -597,22 +589,23 @@ _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 (%u) has address %s %s",
+        os_if->name, os_if->index,
+        netaddr_to_string(&nbuf1, &ip->address),
+        netaddr_to_string(&nbuf2, os_if->if_linklocal_v6)
+        );
 
-    OONF_DEBUG(LOG_AUTO_LL4, "Interface %s has address %s",
-        ifdata->name, netaddr_to_string(&nbuf, ifaddr));
-
-    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;
         }
       }
@@ -637,10 +630,10 @@ _commit_address(struct _nhdp_if_autoll4 *auto_ll4, struct netaddr *addr, bool se
   memcpy(&auto_ll4->os_addr.address, addr, sizeof(*addr));
   auto_ll4->os_addr.set = set;
 
-  OONF_INFO(LOG_AUTO_LL4, "%s address %s on interface %s",
+  OONF_INFO(LOG_AUTO_LL4, "%s address %s on interface %s (%u)",
       auto_ll4->os_addr.set ? "Set" : "Remove",
       netaddr_to_string(&nbuf, &auto_ll4->os_addr.address),
-      if_indextoname(auto_ll4->os_addr.if_index, ibuf));
+      if_indextoname(auto_ll4->os_addr.if_index, ibuf), auto_ll4->os_addr.if_index);
 
   /* remember if the plugin set/reset the address */
   auto_ll4->plugin_generated = set;
@@ -756,37 +749,6 @@ _calculate_host_part(const struct netaddr *addr)
   return htons((hash % (254 * 256)) + 256);
 }
 
-/**
- * Callback triggered when plugin configuration changes
- */
-static void
-_cb_ll4_cfg_changed(void) {
-  struct nhdp_interface *nhdp_if;
-  struct _nhdp_if_autoll4 *auto_ll4;
-  struct _config cfg;
-
-  memset(&cfg, 0, sizeof(cfg));
-  if (cfg_schema_tobin(&cfg, _auto_ll4_section.post,
-      _auto_ll4_entries, ARRAYSIZE(_auto_ll4_entries))) {
-    OONF_WARN(LOG_AUTO_LL4, "Cannot convert " OONF_AUTO_LL4_SUBSYSTEM " configuration.");
-    return;
-  }
-
-  if (cfg.startup_delay == _ll4_startup_delay) {
-    return;
-  }
-
-  avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
-    /* get auto linklayer extension */
-    auto_ll4 = oonf_class_get_extension(&_nhdp_if_extenstion, nhdp_if);
-
-    /* fix update_timer timer if still running */
-    if (!oonf_timer_is_active(&auto_ll4->update_timer)) {
-      oonf_timer_set(&auto_ll4->update_timer, _ll4_startup_delay);
-    }
-  }
-}
-
 /**
  * Plugin triggered when interface auto-configuration parameter changes
  */
@@ -794,9 +756,19 @@ static void
 _cb_if_cfg_changed(void) {
   struct _nhdp_if_autoll4 *auto_ll4;
   struct nhdp_interface *nhdp_if;
+  const char *ifname;
+  char ifbuf[IF_NAMESIZE];
 
-  /* get interface */
-  nhdp_if = nhdp_interface_get(_interface_section.section_name);
+  ifname = cfg_get_phy_if(ifbuf, _interface_section.section_name);
+
+  if (_interface_section.pre == NULL) {
+    /* increase nhdp_interface refcount */
+    nhdp_if = nhdp_interface_add(ifname);
+  }
+  else {
+    /* get interface */
+    nhdp_if = nhdp_interface_get(ifname);
+  }
 
   if (_interface_section.post == NULL) {
     /* section was removed */
@@ -807,11 +779,6 @@ _cb_if_cfg_changed(void) {
     return;
   }
 
-  if (nhdp_if == NULL) {
-    /* increase nhdp_interface refcount */
-    nhdp_if = nhdp_interface_add(_interface_section.section_name);
-  }
-
   /* get auto linklayer extension */
   auto_ll4 = oonf_class_get_extension(&_nhdp_if_extenstion, nhdp_if);
 
@@ -821,7 +788,10 @@ _cb_if_cfg_changed(void) {
     return;
   }
 
-  if (!oonf_timer_is_active(&auto_ll4->update_timer)) {
+  if (!auto_ll4->plugin_generated) {
+    oonf_timer_set(&auto_ll4->update_timer, auto_ll4->startup_delay);
+  }
+  else if (!oonf_timer_is_active(&auto_ll4->update_timer)) {
     /* activate delayed update */
     oonf_timer_set(&auto_ll4->update_timer, 1);
   }
index 8084bc6..393aace 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"
@@ -91,7 +91,7 @@ static int _init(void);
 static void _cleanup(void);
 
 static void _cb_link_added(void *);
-static void _cb_set_linkcost(void *);
+static void _cb_set_linkcost(struct oonf_timer_instance *);
 
 static int _avlcmp_linkcost(const void *, const void *);
 
@@ -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 = {
@@ -238,10 +238,10 @@ _get_linkcost(const char *ifname, const struct netaddr *originator) {
 
 /**
  * Timer callback for delayed setting of new metric values into db
- * @param ptr not used
+ * @param ptr timer instance that fired
  */
 static void
-_cb_set_linkcost(void *ptr __attribute__((unused))) {
+_cb_set_linkcost(struct oonf_timer_instance *ptr __attribute__((unused))) {
   struct nhdp_link *lnk;
   struct _linkcost *entry;
 #ifdef OONF_LOG_DEBUG_INFO
@@ -265,17 +265,17 @@ _cb_set_linkcost(void *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 c57a002..6ba8111 100644 (file)
@@ -122,6 +122,12 @@ struct link_datff_bucket {
  * Additional data for a nhdp_link class for metric calculation
  */
 struct link_datff_data {
+  /*! timer for measuring lost hellos when no further packets are received */
+  struct oonf_timer_instance hello_lost_timer;
+
+  /*! back pointer to NHDP link */
+  struct nhdp_link *nhdp_link;
+
   /*! current position in history ringbuffer */
   int activePtr;
 
@@ -134,9 +140,6 @@ struct link_datff_data {
   /*! remember the last transmitted packet loss for hysteresis */
   uint32_t last_packet_success_rate;
 
-  /*! timer for measuring lost hellos when no further packets are received */
-  struct oonf_timer_instance hello_lost_timer;
-
   /*! last known hello interval */
   uint64_t hello_interval;
 
@@ -158,7 +161,7 @@ static void _cb_link_added(void *);
 static void _cb_link_changed(void *);
 static void _cb_link_removed(void *);
 
-static void _cb_dat_sampling(void *);
+static void _cb_dat_sampling(struct oonf_timer_instance *);
 static void _calculate_link_neighborhood(struct nhdp_link *lnk,
     struct link_datff_data *ldata);
 static int _calculate_dynamic_loss_exponent(int link_neigborhood);
@@ -166,7 +169,7 @@ static uint32_t _apply_packet_loss(struct nhdp_link *lnk,
     struct link_datff_data *ldata,
     uint32_t metric, uint32_t received, uint32_t total);
 
-static void _cb_hello_lost(void *);
+static void _cb_hello_lost(struct oonf_timer_instance *);
 
 static enum rfc5444_result _cb_process_packet(
       struct rfc5444_reader_tlvblock_context *context);
@@ -309,8 +312,6 @@ static struct nhdp_domain_metric _datff_handler = {
   .metric_minimum = DATFF_LINKCOST_MINIMUM,
   .metric_maximum = DATFF_LINKCOST_MAXIMUM,
 
-  .incoming_link_start = DATFF_LINKCOST_START,
-
   .link_to_string = _link_to_string,
   .path_to_string = _path_to_string,
   .internal_link_to_string = _int_link_to_string,
@@ -343,7 +344,7 @@ _init(void) {
   oonf_timer_add(&_sampling_timer_info);
   oonf_timer_add(&_hello_lost_info);
 
-  _protocol = oonf_rfc5444_add_protocol(RFC5444_PROTOCOL, true);
+  _protocol = oonf_rfc5444_get_default_protocol();
 
   oonf_rfc5444_add_protocol_pktseqno(_protocol);
 #ifdef COLLECT_RAW_DATA
@@ -372,7 +373,7 @@ _cleanup(void) {
   nhdp_domain_metric_remove(&_datff_handler);
 
   oonf_rfc5444_remove_protocol_pktseqno(_protocol);
-  oonf_rfc5444_remove_protocol(_protocol);
+  _protocol = NULL;
 
   oonf_class_extension_remove(&_link_extenstion);
 
@@ -428,7 +429,6 @@ _cb_link_added(void *ptr) {
 
   /* start 'hello lost' timer for link */
   data->hello_lost_timer.class = &_hello_lost_info;
-  data->hello_lost_timer.cb_context = ptr;
 }
 
 /**
@@ -512,8 +512,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;
 
@@ -523,13 +522,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;
   }
@@ -553,7 +549,7 @@ _reset_missed_hello_timer(struct link_datff_data *);
  * @param ptr nhdp link
  */
 static void
-_cb_dat_sampling(void *ptr __attribute__((unused))) {
+_cb_dat_sampling(struct oonf_timer_instance *ptr __attribute__((unused))) {
   struct rfc7181_metric_field encoded_metric;
   struct link_datff_data *ldata;
   struct nhdp_link *lnk;
@@ -600,11 +596,6 @@ _cb_dat_sampling(void *ptr __attribute__((unused))) {
       }
     }
 
-    if (total == 0 || received == 0) {
-      nhdp_domain_set_incoming_metric(&_datff_handler, lnk, RFC7181_METRIC_MAX);
-      continue;
-    }
-
     /* update link speed */
     ldata->buckets[ldata->activePtr].scaled_speed = _get_scaled_rx_linkspeed(lnk);
 #ifdef COLLECT_RAW_DATA
@@ -634,7 +625,8 @@ _cb_dat_sampling(void *ptr __attribute__((unused))) {
     }
 
     /* calculate frame loss, use discrete values */
-    if (received * DATFF_FRAME_SUCCESS_RANGE <= total) {
+    if (total == 0 || received == 0
+        || received * DATFF_FRAME_SUCCESS_RANGE <= total) {
       metric *= DATFF_FRAME_SUCCESS_RANGE;
     }
     else {
@@ -785,15 +777,13 @@ _apply_packet_loss(struct nhdp_link *lnk,
 
 /**
  * Callback triggered when the next hellos should have been received
- * @param ptr nhdp link
+ * @param ptr timer instance that fired
  */
 static void
-_cb_hello_lost(void *ptr) {
+_cb_hello_lost(struct oonf_timer_instance *ptr) {
   struct link_datff_data *ldata;
-  struct nhdp_link *lnk;
 
-  lnk = ptr;
-  ldata = oonf_class_get_extension(&_link_extenstion, lnk);
+  ldata = container_of(ptr, struct link_datff_data, hello_lost_timer);
 
   if (ldata->activePtr != -1) {
     ldata->missed_hellos++;
index 8258ba4..41b1d38 100644 (file)
@@ -64,7 +64,6 @@ enum {
   DATFF_LINKSPEED_RANGE = 1<<21,
 
   /* basic statistics of the metric */
-  DATFF_LINKCOST_START    = RFC7181_METRIC_MAX,
   DATFF_LINKCOST_MINIMUM  = RFC7181_METRIC_MIN,
   DATFF_LINKCOST_MAXIMUM  = RFC7181_METRIC_MAX,
 };
index eaac438..e2106f6 100644 (file)
@@ -80,6 +80,12 @@ struct _config {
  * extension of nhdp_link class for hysteresis calculation
  */
 struct link_hysteresis_data {
+  /*! timer until the next NHDP Hello should arrive */
+  struct oonf_timer_instance interval_timer;
+
+  /*! back pointer to NHDP link */
+  struct nhdp_link *nhdp_link;
+
   /*! itime time delivered by neighbors Hello */
   uint64_t itime;
 
@@ -91,9 +97,6 @@ struct link_hysteresis_data {
 
   /*! true if the link is considered lost */
   bool lost;
-
-  /*! timer until the next NHDP Hello should arrive */
-  struct oonf_timer_instance interval_timer;
 };
 
 /* prototypes */
@@ -113,7 +116,7 @@ static bool _cb_is_lost(struct nhdp_link *);
 static const char *_cb_to_string(
     struct nhdp_hysteresis_str *, struct nhdp_link *);
 
-static void _cb_timer_hello_lost(void *);
+static void _cb_timer_hello_lost(struct oonf_timer_instance *);
 static void _cb_cfg_changed(void);
 static int _cb_cfg_validate(const char *section_name,
     struct cfg_named_section *, struct autobuf *);
@@ -263,9 +266,9 @@ _cb_link_added(void *ptr) {
 
   memset(data, 0, sizeof(*data));
   data->pending = true;
+  data->nhdp_link = ptr;
 
   data->interval_timer.class = &_hello_timer_info;
-  data->interval_timer.cb_context = ptr;
 }
 
 /**
@@ -356,16 +359,16 @@ _cb_to_string(struct nhdp_hysteresis_str *buf, struct nhdp_link *lnk) {
 
 /**
  * Timer callback triggered when Hello was lost
- * @param ptr nhdp link
+ * @param ptr timer instance that fired
  */
 static void
-_cb_timer_hello_lost(void *ptr) {
+_cb_timer_hello_lost(struct oonf_timer_instance *ptr) {
   struct link_hysteresis_data *data;
 
-  data = oonf_class_get_extension(&_link_extenstion, ptr);
+  data = container_of(ptr, struct link_hysteresis_data, interval_timer);
 
   /* update hysteresis because of lost Hello */
-  _update_hysteresis(ptr, data, true);
+  _update_hysteresis(data->nhdp_link, data, true);
 
   /* reactivate timer */
   oonf_timer_set(&data->interval_timer, data->itime);
index 265e281..2847640 100644 (file)
@@ -98,8 +98,6 @@ DECLARE_OONF_PLUGIN(_nhdp_mpr_subsystem);
 static struct nhdp_domain_mpr _mpr_handler = {
   .name = OONF_MPR_SUBSYSTEM,
   .update_mpr = _cb_update_mpr,
-  .mpr_start = false,
-  .mprs_start = false,
 };
 
 enum oonf_log_source LOG_MPR;
index 9de8e4c..9278a7f 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"
@@ -101,7 +101,7 @@ struct _probing_link_data {
 static int _init(void);
 static void _cleanup(void);
 static void _cb_link_removed(void *);
-static void _cb_probe_link(void *);
+static void _cb_probe_link(struct oonf_timer_instance *);
 static int _cb_addMessageHeader(struct rfc5444_writer *writer,
     struct rfc5444_writer_message *msg);
 static void _cb_addMessageTLVs(struct rfc5444_writer *);
@@ -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 = {
@@ -184,13 +184,9 @@ static struct rfc5444_writer_content_provider _probing_msg_provider = {
  */
 static int
 _init(void) {
-  if (oonf_class_extension_add(&_link_extenstion)) {
-    return -1;
-  }
+  _protocol = oonf_rfc5444_get_default_protocol();
 
-  _protocol = oonf_rfc5444_add_protocol(RFC5444_PROTOCOL, true);
-  if (_protocol == NULL) {
-    oonf_class_extension_remove(&_link_extenstion);
+  if (oonf_class_extension_add(&_link_extenstion)) {
     return -1;
   }
 
@@ -228,7 +224,7 @@ _cleanup(void) {
       &_protocol->writer, &_probing_msg_provider, NULL, 0);
   rfc5444_writer_unregister_message(
       &_protocol->writer, _probing_message);
-  oonf_rfc5444_remove_protocol(_protocol);
+  _protocol = NULL;
   oonf_timer_remove(&_probe_info);
   oonf_class_extension_remove(&_link_extenstion);
 }
@@ -245,23 +241,24 @@ _cb_link_removed(void *ptr) {
 
 static bool
 _check_if_type(struct oonf_layer2_net *net) {
-  if (net->if_type == OONF_LAYER2_TYPE_WIRELESS) {
-    return true;
+  if (net->if_dlep) {
+    return _probe_config.probe_dlep;
   }
 
-  if (_probe_config.probe_dlep && net->if_type == OONF_LAYER2_TYPE_DLEP) {
-    return true;
-  }
-  return false;
+  return net->if_type == OONF_LAYER2_TYPE_WIRELESS;
 }
 
+/**
+ * Callback for triggering a new neighbor probe
+ * @param ptr timer instance that fired
+ */
 static void
-_cb_probe_link(void *ptr __attribute__((unused))) {
+_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;
 
@@ -279,24 +276,24 @@ _cb_probe_link(void *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 c0f2130..2d5349b 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"
@@ -70,7 +70,7 @@ struct _domain_parameters {
   char mpr_name[NHDP_DOMAIN_MPR_MAXLEN];
 
   /*! routing willingness */
-  uint8_t mpr_willingness;
+  int32_t mpr_willingness;
 };
 
 /**
@@ -81,7 +81,7 @@ struct _generic_parameters {
   char flooding_mpr_name[NHDP_DOMAIN_MPR_MAXLEN];
 
   /*! routing willingness */
-  uint8_t mpr_willingness;
+  int32_t mpr_willingness;
 };
 
 /* prototypes */
@@ -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,
@@ -212,13 +212,8 @@ _early_cfg_init(void) {
  */
 static int
 _init(void) {
-  _protocol = oonf_rfc5444_add_protocol(RFC5444_PROTOCOL, true);
-  if (_protocol == NULL) {
-    return -1;
-  }
-
+  _protocol = oonf_rfc5444_get_default_protocol();
   if (nhdp_writer_init(_protocol)) {
-    oonf_rfc5444_remove_protocol(_protocol);
     return -1;
   }
 
@@ -411,12 +406,16 @@ _cb_cfg_domain_changed(void) {
 static void
 _cb_cfg_interface_changed(void) {
   struct nhdp_interface *interf;
+  const char *ifname;
+  char ifbuf[IF_NAMESIZE];
+
+  ifname = cfg_get_phy_if(ifbuf, _interface_section.section_name);
 
   OONF_DEBUG(LOG_NHDP, "Configuration of NHDP interface %s changed",
       _interface_section.section_name);
 
   /* get interface */
-  interf = nhdp_interface_get(_interface_section.section_name);
+  interf = nhdp_interface_get(ifname);
 
   if (_interface_section.post == NULL) {
     /* section was removed */
@@ -427,7 +426,10 @@ _cb_cfg_interface_changed(void) {
   }
 
   if (interf == NULL) {
-    interf = nhdp_interface_add(_interface_section.section_name);
+    interf = nhdp_interface_add(ifname);
+    if (!interf) {
+      return;
+    }
   }
 
   if (cfg_schema_tobin(interf, _interface_section.post,
index 05062ee..8685f29 100644 (file)
@@ -64,11 +64,11 @@ static void _link_status_now_symmetric(struct nhdp_link *lnk);
 static void _link_status_not_symmetric_anymore(struct nhdp_link *lnk);
 int _nhdp_db_link_calculate_status(struct nhdp_link *lnk);
 
-static void _cb_link_vtime(void *);
-static void _cb_link_heard(void *);
-static void _cb_link_symtime(void *);
-static void _cb_l2hop_vtime(void *);
-static void _cb_naddr_vtime(void *);
+static void _cb_link_vtime(struct oonf_timer_instance *);
+static void _cb_link_heard(struct oonf_timer_instance *);
+static void _cb_link_symtime(struct oonf_timer_instance *);
+static void _cb_l2hop_vtime(struct oonf_timer_instance *);
+static void _cb_naddr_vtime(struct oonf_timer_instance *);
 
 /* Link status names */
 static const char *_LINK_PENDING   = "pending";
@@ -244,6 +244,9 @@ nhdp_db_neighbor_remove(struct nhdp_neighbor *neigh) {
   /* trigger event */
   oonf_class_event(&_neigh_info, neigh, OONF_OBJECT_REMOVED);
 
+  /* disconnect from other IP version */
+  nhdp_db_neigbor_disconnect_dualstack(neigh);
+
   /* remove all links */
   list_for_each_element_safe(&neigh->_links, lnk, _neigh_node, l_it) {
     nhdp_db_link_remove(lnk);
@@ -372,7 +375,6 @@ nhdp_db_neighbor_addr_add(struct nhdp_neighbor *neigh,
 
   /* initialize timer for lost addresses */
   naddr->_lost_vtime.class = &_naddr_vtime_info;
-  naddr->_lost_vtime.cb_context = naddr;
 
   /* add to trees */
   avl_insert(&_naddr_tree, &naddr->_global_node);
@@ -537,11 +539,8 @@ nhdp_db_link_add(struct nhdp_neighbor *neigh, struct nhdp_interface *local_if) {
 
   /* init timers */
   lnk->sym_time.class = &_link_symtime_info;
-  lnk->sym_time.cb_context = lnk;
   lnk->heard_time.class = &_link_heard_info;
-  lnk->heard_time.cb_context = lnk;
   lnk->vtime.class = &_link_vtime_info;
-  lnk->vtime.cb_context = lnk;
 
   /* add to originator tree if set */
   lnk->_originator_node.key = &neigh->originator;
@@ -729,7 +728,6 @@ nhdp_db_link_2hop_add(struct nhdp_link *lnk, const struct netaddr *addr) {
 
   /* initialize validity timer */
   l2hop->_vtime.class = &_l2hop_vtime_info;
-  l2hop->_vtime.cb_context = l2hop;
 
   /* add to link tree */
   avl_insert(&lnk->_2hop, &l2hop->_link_node);
@@ -949,13 +947,14 @@ _link_status_not_symmetric_anymore(struct nhdp_link *lnk) {
 
 /**
  * Callback triggered when link validity timer fires
- * @param ptr nhdp link
+ * @param ptr timer instance that fired
  */
 static void
-_cb_link_vtime(void *ptr) {
-  struct nhdp_link *lnk = ptr;
+_cb_link_vtime(struct oonf_timer_instance *ptr) {
+  struct nhdp_link *lnk;
   struct nhdp_neighbor *neigh;
 
+  lnk = container_of(ptr, struct nhdp_link, vtime);
   OONF_DEBUG(LOG_NHDP, "Link vtime fired: 0x%0zx", (size_t)ptr);
 
   neigh = lnk->neigh;
@@ -975,25 +974,29 @@ _cb_link_vtime(void *ptr) {
 
 /**
  * Callback triggered when link heard timer fires
- * @param ptr nhdp link
+ * @param ptr timer instance that fired
  */
 static void
-_cb_link_heard(void *ptr) {
-  OONF_DEBUG(LOG_NHDP, "Link heard fired: 0x%0zx", (size_t)ptr);
-  nhdp_db_link_update_status(ptr);
+_cb_link_heard(struct oonf_timer_instance *ptr) {
+  struct nhdp_link *lnk;
+
+  lnk = container_of(ptr, struct nhdp_link, heard_time);
+  OONF_DEBUG(LOG_NHDP, "Link heard fired: 0x%0zx", (size_t)lnk);
+  nhdp_db_link_update_status(lnk);
 }
 
 /**
  * Callback triggered when link symmetric timer fires
- * @param ptr nhdp link
+ * @param ptr timer instance that fired
  */
 static void
-_cb_link_symtime(void *ptr) {
-  struct nhdp_link *lnk = ptr;
+_cb_link_symtime(struct oonf_timer_instance *ptr) {
+  struct nhdp_link *lnk;
   struct nhdp_neighbor_domaindata *data;
   struct nhdp_domain *domain;
 
-  OONF_DEBUG(LOG_NHDP, "Link Symtime fired: 0x%0zx", (size_t)ptr);
+  lnk = container_of(ptr, struct nhdp_link, sym_time);
+  OONF_DEBUG(LOG_NHDP, "Link Symtime fired: 0x%0zx", (size_t)lnk);
   nhdp_db_link_update_status(lnk);
 
   list_for_each_element(nhdp_domain_get_list(), domain, _node) {
@@ -1007,12 +1010,13 @@ _cb_link_symtime(void *ptr) {
 
 /**
  * Callback triggered when nhdp address validity timer fires
- * @param ptr nhdp address
+ * @param ptr timer instance that fired
  */
 static void
-_cb_naddr_vtime(void *ptr) {
-  struct nhdp_naddr *naddr = ptr;
+_cb_naddr_vtime(struct oonf_timer_instance *ptr) {
+  struct nhdp_naddr *naddr;
 
+  naddr = container_of(ptr, struct nhdp_naddr, _lost_vtime);
   OONF_DEBUG(LOG_NHDP, "Neighbor Address Lost fired: 0x%0zx", (size_t)ptr);
 
   nhdp_db_neighbor_addr_remove(naddr);
@@ -1020,11 +1024,13 @@ _cb_naddr_vtime(void *ptr) {
 
 /**
  * Callback triggered when 2hop valitidy timer fires
- * @param ptr nhdp 2hop address
+ * @param ptr timer instance that fired
  */
 static void
-_cb_l2hop_vtime(void *ptr) {
-  struct nhdp_l2hop *l2hop = ptr;
+_cb_l2hop_vtime(struct oonf_timer_instance *ptr) {
+  struct nhdp_l2hop *l2hop;
+
+  l2hop = container_of(ptr, struct nhdp_l2hop, _vtime);
 
   OONF_DEBUG(LOG_NHDP, "2Hop vtime fired: 0x%0zx", (size_t)ptr);
   nhdp_db_link_2hop_remove(l2hop);
index afb27ed..defcaf6 100644 (file)
@@ -104,9 +104,6 @@ static struct nhdp_domain_metric _no_metric = {
 static struct nhdp_domain_mpr _everyone_mprs = {
   .name = "Everyone MPR",
 
-  .mpr_start = true,
-  .mprs_start = true,
-
   .update_mpr = _cb_update_everyone_mpr,
 };
 
@@ -339,14 +336,16 @@ nhdp_domain_init_link(struct nhdp_link *lnk) {
 
   /* initialize metrics */
   for (i=0; i<NHDP_MAXIMUM_DOMAINS; i++) {
-    lnk->_domaindata[i].metric.in = RFC7181_METRIC_MAX;
-    lnk->_domaindata[i].metric.out = RFC7181_METRIC_MAX;
+    lnk->_domaindata[i].metric.in = RFC7181_METRIC_INFINITE;
+    lnk->_domaindata[i].metric.out = RFC7181_METRIC_INFINITE;
   }
   list_for_each_element(&_domain_list, domain, _node) {
     data = nhdp_domain_get_linkdata(domain, lnk);
 
-    data->metric.in = domain->metric->incoming_link_start;
-    data->metric.out = domain->metric->outgoing_link_start;
+    if (domain->metric->no_default_handling) {
+      data->metric.in = domain->metric->incoming_link_start;
+      data->metric.out = domain->metric->outgoing_link_start;
+    }
   }
 }
 
@@ -362,15 +361,17 @@ nhdp_domain_init_l2hop(struct nhdp_l2hop *l2hop) {
 
   /* initialize metrics */
   for (i=0; i<NHDP_MAXIMUM_DOMAINS; i++) {
-    l2hop->_domaindata[i].metric.in = RFC7181_METRIC_MAX;
-    l2hop->_domaindata[i].metric.out = RFC7181_METRIC_MAX;
+    l2hop->_domaindata[i].metric.in = RFC7181_METRIC_INFINITE;
+    l2hop->_domaindata[i].metric.out = RFC7181_METRIC_INFINITE;
   }
 
   list_for_each_element(&_domain_list, domain, _node) {
     data = nhdp_domain_get_l2hopdata(domain, l2hop);
 
-    data->metric.in = domain->metric->incoming_2hop_start;
-    data->metric.out = domain->metric->outgoing_2hop_start;
+    if (domain->metric->no_default_handling) {
+      data->metric.in = domain->metric->incoming_2hop_start;
+      data->metric.out = domain->metric->outgoing_2hop_start;
+    }
   }
 }
 
@@ -386,26 +387,29 @@ nhdp_domain_init_neighbor(struct nhdp_neighbor *neigh) {
 
   /* initialize flooding MPR settings */
   neigh->flooding_willingness = RFC7181_WILLINGNESS_NEVER;
-  neigh->local_is_flooding_mpr = _flooding_domain.mpr->mprs_start;
-  neigh->neigh_is_flooding_mpr = _flooding_domain.mpr->mpr_start;
+  neigh->local_is_flooding_mpr = false;
+  neigh->neigh_is_flooding_mpr = false;
 
   for (i=0; i<NHDP_MAXIMUM_DOMAINS; i++) {
-    neigh->_domaindata[i].metric.in = RFC7181_METRIC_MAX;
-    neigh->_domaindata[i].metric.out = RFC7181_METRIC_MAX;
+    neigh->_domaindata[i].metric.in = RFC7181_METRIC_INFINITE;
+    neigh->_domaindata[i].metric.out = RFC7181_METRIC_INFINITE;
+
+    neigh->_domaindata[i].best_link = NULL;
+    neigh->_domaindata[i].willingness = RFC7181_WILLINGNESS_NEVER;
+
+
+    neigh->_domaindata[i].local_is_mpr = false;
+    neigh->_domaindata[i].neigh_is_mpr = false;
   }
 
   /* initialize metrics and mprs */
   list_for_each_element(&_domain_list, domain, _node) {
     data = nhdp_domain_get_neighbordata(domain, neigh);
 
-    data->metric.in = domain->metric->incoming_link_start;
-    data->metric.out = domain->metric->outgoing_link_start;
-
-    data->best_link = NULL;
-
-    data->willingness = RFC7181_WILLINGNESS_NEVER;
-    data->local_is_mpr = domain->mpr->mprs_start;
-    data->neigh_is_mpr = domain->mpr->mpr_start;
+    if (domain->metric->no_default_handling) {
+      data->metric.in = domain->metric->incoming_link_start;
+      data->metric.out = domain->metric->outgoing_link_start;
+    }
   }
 }
 
@@ -930,6 +934,9 @@ _recalculate_neighbor_metric(
   struct nhdp_neighbor_domaindata *neighdata;
   uint32_t old_outgoing;
   bool changed;
+#ifdef OONF_LOG_DEBUG_INFO
+  struct netaddr_str nbuf;
+#endif
 
   neighdata = nhdp_domain_get_neighbordata(domain, neigh);
   changed = false;
@@ -945,6 +952,9 @@ _recalculate_neighbor_metric(
   neighdata->best_link = NULL;
   neighdata->best_link_ifindex = 0;
 
+  OONF_DEBUG(LOG_NHDP, "Recalculate neighbor %s metrics (ext %u):",
+      netaddr_to_string(&nbuf, &neigh->originator), domain->ext);
+
   /* get best metric */
   list_for_each_element(&neigh->_links, lnk, _neigh_node) {
     if (lnk->status != NHDP_LINK_SYMMETRIC) {
@@ -953,10 +963,17 @@ _recalculate_neighbor_metric(
 
     linkdata = nhdp_domain_get_linkdata(domain, lnk);
     if (linkdata->metric.out < neighdata->metric.out) {
+      OONF_DEBUG(LOG_NHDP, "Link on if %s has better outgoing metric: %u",
+              lnk->local_if->os_if_listener.data->name,
+              linkdata->metric.out);
+
       neighdata->metric.out = linkdata->metric.out;
       neighdata->best_link = lnk;
     }
     if (linkdata->metric.in < neighdata->metric.in) {
+      OONF_DEBUG(LOG_NHDP, "Link on if %s has better incoming metric: %u",
+              lnk->local_if->os_if_listener.data->name,
+              linkdata->metric.in);
       neighdata->metric.in = linkdata->metric.in;
     }
 
@@ -970,8 +987,10 @@ _recalculate_neighbor_metric(
   }
 
   if (neighdata->best_link != NULL) {
+    OONF_DEBUG(LOG_NHDP, "Best link if: %s",
+        nhdp_interface_get_if_listener(neighdata->best_link->local_if)->data->name);
     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;
   }
   return changed || neighdata->metric.out != old_outgoing;
 }
index 9c56af4..c5e8f15 100644 (file)
@@ -88,16 +88,16 @@ struct nhdp_domain_metric {
   /*! maximum metric value */
   uint32_t metric_maximum;
 
-  /*! default incoming link metric */
+  /*! default incoming link metric for "no default handling" metrics */
   uint32_t incoming_link_start;
 
-  /*! default outgoing link metric */
+  /*! default outgoing link metric for "no default handling" metrics */
   uint32_t outgoing_link_start;
 
-  /*! default incoming 2-hop link metric */
+  /*! default incoming 2-hop link metric for "no default handling" metrics */
   uint32_t incoming_2hop_start;
 
-  /*! default outgoing 2-hop link metric */
+  /*! default outgoing 2-hop link metric for "no default handling" metrics */
   uint32_t outgoing_2hop_start;
 
   /*! true if metrics should not be handled by nhdp reader/writer */
@@ -173,12 +173,6 @@ struct nhdp_domain_mpr {
    */
   void (*disable)(void);
 
-  /*! default value for neighbor MPR setting */
-  bool mpr_start;
-
-  /*! default value for local MPR (selector) setting */
-  bool mprs_start;
-
   /*! reference count */
   int _refcount;
 
index 9d15974..2da87c8 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"
 /* Prototypes of local functions */
 static void _addr_add(struct nhdp_interface *, struct netaddr *addr);
 static void _addr_remove(struct nhdp_interface_addr *addr, uint64_t vtime);
-static void _cb_remove_addr(void *ptr);
+static void _remove_addr(struct nhdp_interface_addr *ptr);
+static void _cb_addr_timeout(struct oonf_timer_instance *ptr);
 
 static int avl_comp_ifaddr(const void *k1, const void *k2);
 
-static void _cb_generate_hello(void *ptr);
+static void _cb_generate_hello(struct oonf_timer_instance *ptr);
 static void _cb_interface_event(struct oonf_rfc5444_interface_listener *, bool);
 
 /* global tree of nhdp interfaces, filters and addresses */
@@ -97,7 +98,7 @@ static struct oonf_class _addr_info = {
 
 static struct oonf_timer_class _removed_address_hold_timer = {
   .name = "NHDP interface removed address hold timer",
-  .callback = _cb_remove_addr,
+  .callback = _cb_addr_timeout,
 };
 
 /* other global variables */
@@ -225,12 +226,11 @@ 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;
-    interf->_hello_timer.cb_context = interf;
 
     /* hook into global interface tree */
     interf->_node.key = interf->rfc5444_if.interface->name;
@@ -299,7 +299,7 @@ nhdp_interface_remove(struct nhdp_interface *interf) {
   oonf_timer_stop(&interf->_hello_timer);
 
   avl_for_each_element_safe(&interf->_if_addresses, addr, _if_node, a_it) {
-    _cb_remove_addr(addr);
+    _remove_addr(addr);
   }
 
   list_for_each_element_safe(&interf->_links, lnk, _if_node, l_it) {
@@ -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);
 }
@@ -387,7 +387,6 @@ _addr_add(struct nhdp_interface *interf, struct netaddr *addr) {
 
     /* initialize validity timer for removed addresses */
     if_addr->_vtime.class = &_removed_address_hold_timer;
-    if_addr->_vtime.cb_context = if_addr;
 
     /* trigger event */
     oonf_class_event(&_addr_info, if_addr, OONF_OBJECT_ADDED);
@@ -419,16 +418,11 @@ _addr_remove(struct nhdp_interface_addr *addr, uint64_t vtime) {
 }
 
 /**
- * Callback triggered when an address from a nhdp interface
- *  should be removed from the db
+ * remove address from NHDP interface
  * @param ptr pointer to nhdp interface address
  */
 static void
-_cb_remove_addr(void *ptr) {
-  struct nhdp_interface_addr *addr;
-
-  addr = ptr;
-
+_remove_addr(struct nhdp_interface_addr *addr) {
   /* trigger event */
   oonf_class_event(&_addr_info, addr, OONF_OBJECT_REMOVED);
 
@@ -438,6 +432,18 @@ _cb_remove_addr(void *ptr) {
   oonf_class_free(&_addr_info, addr);
 }
 
+/**
+ * Callback when an interface address times out
+ * @param ptr timer instance that fired
+ */
+static void
+_cb_addr_timeout(struct oonf_timer_instance *ptr) {
+  struct nhdp_interface_addr *addr;
+
+  addr = container_of(ptr, struct nhdp_interface_addr, _vtime);
+  _remove_addr(addr);
+}
+
 /**
  * AVL tree comparator for netaddr objects.
  * @param k1 pointer to key 1
@@ -462,11 +468,14 @@ avl_comp_ifaddr(const void *k1, const void *k2) {
 
 /**
  * Callback triggered to generate a Hello on an interface
- * @param ptr pointer to nhdp interface
+ * @param ptr timer instance that fired
  */
 static void
-_cb_generate_hello(void *ptr) {
-  nhdp_writer_send_hello(ptr);
+_cb_generate_hello(struct oonf_timer_instance *ptr) {
+  struct nhdp_interface *nhdp_if;
+
+  nhdp_if = container_of(ptr, struct nhdp_interface, _hello_timer);
+  nhdp_writer_send_hello(nhdp_if);
 }
 
 /**
@@ -480,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
@@ -500,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->flags.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 400e361..c28a639 100644 (file)
@@ -386,11 +386,6 @@ _cb_messagetlvs(struct rfc5444_reader_tlvblock_context *context) {
       context->msg_type, netaddr_socket_to_string(&buf, _protocol->input_socket),
       _protocol->input_interface->name, context->addr_len);
 
-  if (!_protocol->input_is_multicast) {
-    /* NHDP doesn't care about unicast messages */
-    return RFC5444_DROP_MESSAGE;
-  }
-
   switch (context->addr_len) {
     case 4:
       af_type = AF_INET;
@@ -411,6 +406,10 @@ _cb_messagetlvs(struct rfc5444_reader_tlvblock_context *context) {
 
   /* remember local NHDP interface */
   _current.localif = nhdp_interface_get(_protocol->input_interface->name);
+  if (!_current.localif) {
+    /* incoming message through an interface unspecific socket, ignore it */
+    return RFC5444_DROP_MESSAGE;
+  }
 
   /* extract originator address */
   if (context->has_origaddr) {
index 595c800..2e67e5b 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->flags.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));
   }
 }
 
@@ -466,6 +463,11 @@ _write_metric_tlv(struct rfc5444_writer *writer, struct rfc5444_writer_address *
       RFC7181_LINKMETRIC_INCOMING_NEIGH,
       RFC7181_LINKMETRIC_OUTGOING_NEIGH,
   };
+#ifdef OONF_LOG_DEBUG_INFO
+  static const char *lq_name[4] = {
+    "l_in", "l_out", "n_in", "n_out",
+  };
+#endif
   struct nhdp_link_domaindata *linkdata;
   struct nhdp_neighbor_domaindata *neighdata;
   struct rfc7181_metric_field metric_encoded[4], tlv_value;
@@ -523,17 +525,20 @@ _write_metric_tlv(struct rfc5444_writer *writer, struct rfc5444_writer_address *
     rfc7181_metric_set_flag(&tlv_value, flags[i]);
 
     /* mark all metric pair that have the same linkmetric */
+    OONF_DEBUG(LOG_NHDP_W, "Add Metric %s (ext %u): 0x%02x%02x (%u)",
+        lq_name[i], domain->ext, tlv_value.b[0], tlv_value.b[1], metrics[i]);
+
     for (j=3; j>i; j--) {
       if (metrics[j] > 0 &&
           memcmp(&metric_encoded[i], &metric_encoded[j], sizeof(metric_encoded[0])) == 0) {
         rfc7181_metric_set_flag(&tlv_value, flags[j]);
         metrics[j] = 0;
+
+        OONF_DEBUG(LOG_NHDP_W, "Same metrics for %s (ext %u)",
+            lq_name[j], domain->ext);
       }
     }
 
-    OONF_DEBUG(LOG_NHDP_W, "Add Metric (ext %u): 0x%02x%02x (%u)",
-        domain->ext, tlv_value.b[0], tlv_value.b[1], metrics[i]);
-
     /* add to rfc5444 address */
     rfc5444_writer_add_addrtlv(writer, addr,
         &domain->_metric_addrtlvs[k++],
index 445c98a..3f39a88 100644 (file)
@@ -133,7 +133,7 @@ static struct oonf_rfc5444_protocol *_protocol = NULL;
  */
 static int
 _init(void) {
-  _protocol = oonf_rfc5444_add_protocol(RFC5444_PROTOCOL, true);
+  _protocol = oonf_rfc5444_get_default_protocol();
   if (_protocol == NULL) {
     return -1;
   }
@@ -157,8 +157,6 @@ _cleanup(void) {
       &_protocol->reader, &_nhdp_message_consumer);
   rfc5444_reader_remove_message_consumer(
       &_protocol->reader, &_nhdp_address_consumer);
-
-  oonf_rfc5444_remove_protocol(_protocol);
   _protocol = NULL;
 }
 
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 732e1e5..5e455d6 100644 (file)
@@ -110,8 +110,8 @@ static void _cb_cfg_changed(void);
 
 /* plugin declaration */
 static struct cfg_schema_entry _import_entries[] = {
-  CFG_MAP_INT32_MINMAX(_import_entry, domain, "domain", "0",
-      "Routing domain extension for filter", 0, false, 0, 255),
+  CFG_MAP_INT32_MINMAX(_import_entry, domain, "domain", "-1",
+      "Routing domain extension for filter, -1 for all domains", 0, false, -1, 255),
   CFG_MAP_ACL(_import_entry, filter, "matches",  ACL_DEFAULT_ACCEPT,
       "Ip addresses the filter shou