mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
ng_ipv6: provide support for ng_netif
This commit is contained in:
parent
89a10f2630
commit
7027519f28
@ -52,6 +52,11 @@ ifneq (,$(filter ng_ipv6_nc,$(USEMODULE)))
|
||||
USEMODULE += ng_ipv6_addr
|
||||
endif
|
||||
|
||||
ifneq (,$(filter ng_ipv6_netif,$(USEMODULE)))
|
||||
USEMODULE += ng_ipv6_addr
|
||||
USEMODULE += ng_netif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter ng_netbase,$(USEMODULE)))
|
||||
USEMODULE += ng_netapi
|
||||
USEMODULE += ng_netreg
|
||||
|
@ -68,6 +68,9 @@ endif
|
||||
ifneq (,$(filter ng_ipv6_nc,$(USEMODULE)))
|
||||
DIRS += net/network_layer/ng_ipv6/nc
|
||||
endif
|
||||
ifneq (,$(filter ng_ipv6_netif,$(USEMODULE)))
|
||||
DIRS += net/network_layer/ng_ipv6/netif
|
||||
endif
|
||||
ifneq (,$(filter ng_netapi,$(USEMODULE)))
|
||||
DIRS += net/crosslayer/ng_netapi
|
||||
endif
|
||||
|
@ -23,12 +23,20 @@
|
||||
#define NG_IPV6_H_
|
||||
|
||||
#include "net/ng_ipv6/addr.h"
|
||||
#include "net/ng_ipv6/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Default maximum transition unit
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc2460#section-5">
|
||||
* RFC 2460, section 5
|
||||
* </a>
|
||||
*/
|
||||
#define NG_IPV6_DEFAULT_MTU (1280)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
254
sys/include/net/ng_ipv6/netif.h
Normal file
254
sys/include/net/ng_ipv6/netif.h
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup net_ng_ipv6_netif IPv6 network interfaces
|
||||
* @ingroup net_ng_ipv6
|
||||
* @brief IPv6 specific information on @ref net_ng_netif.
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Definitions for IPv6 specific information of network interfaces.
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef NG_IPV6_NETIF_H_
|
||||
#define NG_IPV6_NETIF_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kernel_macros.h"
|
||||
#include "kernel_types.h"
|
||||
#include "mutex.h"
|
||||
#include "net/ng_ipv6/addr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def NG_IPV6_NETIF_ADDR_NUMOF
|
||||
*
|
||||
* @brief Number of IPv6 addresses per interface.
|
||||
*/
|
||||
#ifndef NG_IPV6_NETIF_ADDR_NUMOF
|
||||
#ifdef MODULE_NG_IPV6_ROUTER
|
||||
#define NG_IPV6_NETIF_ADDR_NUMOF (5) /* router needs all-routers multicast address */
|
||||
#else
|
||||
#define NG_IPV6_NETIF_ADDR_NUMOF (4)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Flags for a registered IPv6 address.
|
||||
* @brief Needed primarily to identify addresses as either anycast or unicast.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc4291#section-2.6">
|
||||
* RFC 4291, section 2.6
|
||||
* </a>
|
||||
*/
|
||||
#define NG_IPV6_NETIF_FLAGS_UNICAST (0x00) /**< unicast address */
|
||||
#define NG_IPV6_NETIF_FLAGS_NON_UNICAST (0x01) /**< non-unicast address */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Type to represent an IPv6 address registered to an interface.
|
||||
*/
|
||||
typedef struct {
|
||||
ng_ipv6_addr_t addr; /**< The address data */
|
||||
uint8_t flags; /**< flags */
|
||||
} ng_ipv6_netif_addr_t;
|
||||
|
||||
/**
|
||||
* @brief Definition of IPv6 interface type.
|
||||
*/
|
||||
typedef struct {
|
||||
ng_ipv6_netif_addr_t addrs[NG_IPV6_NETIF_ADDR_NUMOF]; /**< addresses registered
|
||||
* to the interface */
|
||||
mutex_t mutex; /**< mutex for the interface */
|
||||
kernel_pid_t pid; /**< PID of the interface */
|
||||
uint16_t mtu; /**< Maximum Transmission Unit (MTU) of the interface */
|
||||
} ng_ipv6_netif_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the module.
|
||||
*/
|
||||
void ng_ipv6_netif_init(void);
|
||||
|
||||
/**
|
||||
* @brief Add interface to IPv6.
|
||||
*
|
||||
* @details This function will be called by @ref ng_netif_add().
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
*/
|
||||
void ng_ipv6_netif_add(kernel_pid_t pid);
|
||||
|
||||
/**
|
||||
* @brief Remove interface from IPv6.
|
||||
*
|
||||
* @details This function will be called by @ref ng_netif_remove().
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
*/
|
||||
void ng_ipv6_netif_remove(kernel_pid_t pid);
|
||||
|
||||
/**
|
||||
* @brief Get interface.
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
*
|
||||
* @return The interface describing structure, on success.
|
||||
* @return NULL, if there is no interface with PID @p pid.
|
||||
*/
|
||||
ng_ipv6_netif_t *ng_ipv6_netif_get(kernel_pid_t pid);
|
||||
|
||||
/**
|
||||
* @brief Adds an address to an interface.
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
* @param[in] addr An address you want to add to the interface.
|
||||
* @param[in] anycast If @p addr should be an anycast address, @p anycast
|
||||
* must be true. Otherwise set it false.
|
||||
* If @p addr is a multicast address, @p anycast will be
|
||||
* ignored.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc4291#section-2.6">
|
||||
* RFC 4291, section 2.6
|
||||
* </a>
|
||||
*
|
||||
* @return 0, on success.
|
||||
* @return -EINVAL, if @p addr is NULL or unspecified address.
|
||||
* @return -ENOENT, if @p pid is no interface.
|
||||
* @return -ENOMEM, if there is no space left to store @p addr.
|
||||
*/
|
||||
int ng_ipv6_netif_add_addr(kernel_pid_t pid, const ng_ipv6_addr_t *addr,
|
||||
bool anycast);
|
||||
|
||||
/**
|
||||
* @brief Remove an address from the interface.
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
* @param[in] addr An address you want to remove from interface.
|
||||
*/
|
||||
void ng_ipv6_netif_remove_addr(kernel_pid_t pid, ng_ipv6_addr_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Removes all addresses from the interface.
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
*/
|
||||
void ng_ipv6_netif_reset_addr(kernel_pid_t pid);
|
||||
|
||||
/**
|
||||
* @brief Searches for an address on all interfaces.
|
||||
*
|
||||
* @param[out] out The reference to the address on the interface.
|
||||
* @param[in] addr The address you want to search for.
|
||||
*
|
||||
* @return The PID to the interface the address is registered to.
|
||||
* @return KERNEL_PID_UNDEF, if the address can not be found on any interface.
|
||||
*/
|
||||
kernel_pid_t ng_ipv6_netif_find_by_addr(ng_ipv6_addr_t **out,
|
||||
const ng_ipv6_addr_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Searches for an address on an interface.
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
* @param[in] addr The address you want to search for.
|
||||
*
|
||||
* @return The reference to the address on the interface.
|
||||
* @return NULL, if the address can not be found on the interface.
|
||||
* @return NULL, if @p pid is no interface.
|
||||
*/
|
||||
ng_ipv6_addr_t *ng_ipv6_netif_find_addr(kernel_pid_t pid,
|
||||
const ng_ipv6_addr_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Searches for the first address matching a prefix best on all
|
||||
* interfaces.
|
||||
*
|
||||
* @param[out] out The reference to the found address on the interface.
|
||||
* @param[in] prefix The prefix you want to search for.
|
||||
*
|
||||
* @return The PID to the interface the address is registered to.
|
||||
* @return KERNEL_PID_UNDEF, if no matching address can not be found on any
|
||||
* interface.
|
||||
*/
|
||||
kernel_pid_t ng_ipv6_netif_find_by_prefix(ng_ipv6_addr_t **out,
|
||||
const ng_ipv6_addr_t *prefix);
|
||||
|
||||
/**
|
||||
* @brief Searches for the first address matching a prefix best on an
|
||||
* interfaces.
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
* @param[in] prefix The prefix you want to search for.
|
||||
*
|
||||
* @return The reference to the found address on the interface.
|
||||
* @return NULL, if no matching address can be found on the interface.
|
||||
* @return NULL, if @p pid is no interface.
|
||||
*/
|
||||
ng_ipv6_addr_t *ng_ipv6_netif_match_prefix(kernel_pid_t pid,
|
||||
const ng_ipv6_addr_t *prefix);
|
||||
|
||||
/**
|
||||
* @brief Searches for the best address on an interface usable as a
|
||||
* source address for a given destination address.
|
||||
*
|
||||
* @param[in] pid The PID to the interface.
|
||||
* @param[in] dest The destination address you want to find a destination
|
||||
* address for.
|
||||
*
|
||||
* @return The reference to the found address on the interface.
|
||||
* @return NULL, if no matching address can be found on the interface.
|
||||
* @return NULL, if @p pid is no interface.
|
||||
*/
|
||||
ng_ipv6_addr_t *ng_ipv6_netif_find_best_src_addr(kernel_pid_t pid, const ng_ipv6_addr_t *dest);
|
||||
|
||||
/**
|
||||
* @brief Checks if an address is non-unicast.
|
||||
*
|
||||
* @details This only works with addresses you retrieved via the following
|
||||
* functions:
|
||||
*
|
||||
* * ng_ipv6_find_addr()
|
||||
* * ng_ipv6_find_addr_local()
|
||||
* * ng_ipv6_find_prefix_match()
|
||||
* * ng_ipv6_find_prefix_match_local()
|
||||
* * ng_ipv6_find_best_src_address
|
||||
*
|
||||
* The behaviour for other addresses is undefined.
|
||||
*
|
||||
* @param[in] addr The address you want to check.
|
||||
*
|
||||
* @return true, if address is anycast or multicast.
|
||||
* @return false, if address is unicast.
|
||||
*/
|
||||
static inline bool ng_ipv6_netif_addr_is_non_unicast(const ng_ipv6_addr_t *addr)
|
||||
{
|
||||
return (bool)(container_of(addr, ng_ipv6_netif_addr_t, addr)->flags &
|
||||
NG_IPV6_NETIF_FLAGS_NON_UNICAST);
|
||||
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NETIF_H_ */
|
||||
/**
|
||||
* @}
|
||||
*/
|
@ -18,12 +18,16 @@
|
||||
#include "kernel_types.h"
|
||||
#include "net/ng_netif.h"
|
||||
|
||||
static ng_netif_handler_t if_handler[] = {
|
||||
#ifdef MODULE_NG_IPV6
|
||||
{ ipv6_if_add, ipv6_if_remove },
|
||||
#ifdef MODULE_NG_IPV6_NETIF
|
||||
#include "net/ng_ipv6/netif.h"
|
||||
#endif
|
||||
/* #ifdef MODULE_NG_IPV4
|
||||
* { ipv4_if_add, ipv4_if_remove },
|
||||
|
||||
static ng_netif_handler_t if_handler[] = {
|
||||
#ifdef MODULE_NG_IPV6_NETIF
|
||||
{ ng_ipv6_netif_add, ng_ipv6_netif_remove },
|
||||
#endif
|
||||
/* #ifdef MODULE_NG_IPV4_NETIF
|
||||
* { ipv4_netif_add, ipv4_netif_remove },
|
||||
* #endif ... you get the idea
|
||||
*/
|
||||
{ NULL, NULL }
|
||||
|
3
sys/net/network_layer/ng_ipv6/netif/Makefile
Normal file
3
sys/net/network_layer/ng_ipv6/netif/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = ng_ipv6_netif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
382
sys/net/network_layer/ng_ipv6/netif/ng_ipv6_netif.c
Normal file
382
sys/net/network_layer/ng_ipv6/netif/ng_ipv6_netif.c
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup sys_net_ng_ipv6_netif
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "mutex.h"
|
||||
#include "net/ng_ipv6.h"
|
||||
#include "net/ng_ipv6/addr.h"
|
||||
#include "net/ng_netif.h"
|
||||
|
||||
#include "net/ng_ipv6/netif.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
static ng_ipv6_netif_t ipv6_ifs[NG_NETIF_NUMOF];
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
static char addr_str[NG_IPV6_ADDR_MAX_STR_LEN];
|
||||
#endif
|
||||
|
||||
static int _add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr,
|
||||
bool anycast)
|
||||
{
|
||||
for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
|
||||
if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr))) {
|
||||
DEBUG("Add %s to interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
entry->pid);
|
||||
memcpy(&(entry->addrs[i].addr), addr, sizeof(ng_ipv6_addr_t));
|
||||
|
||||
if (anycast || ng_ipv6_addr_is_multicast(addr)) {
|
||||
entry->addrs[i].flags = NG_IPV6_NETIF_FLAGS_NON_UNICAST;
|
||||
}
|
||||
else {
|
||||
entry->addrs[i].flags = NG_IPV6_NETIF_FLAGS_UNICAST;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void _reset_addr_from_entry(ng_ipv6_netif_t *entry)
|
||||
{
|
||||
DEBUG("Reset IPv6 addresses on interface %" PRIkernel_pid "\n", entry->pid);
|
||||
memset(entry->addrs, 0, sizeof(entry->addrs));
|
||||
}
|
||||
|
||||
void ng_ipv6_netif_init(void)
|
||||
{
|
||||
for (int i = 0; i < NG_NETIF_NUMOF; i++) {
|
||||
mutex_init(&(ipv6_ifs[i].mutex));
|
||||
mutex_lock(&(ipv6_ifs[i].mutex));
|
||||
_reset_addr_from_entry(&ipv6_ifs[i]);
|
||||
ipv6_ifs[i].pid = KERNEL_PID_UNDEF;
|
||||
mutex_unlock(&(ipv6_ifs[i].mutex));
|
||||
}
|
||||
}
|
||||
|
||||
void ng_ipv6_netif_add(kernel_pid_t pid)
|
||||
{
|
||||
for (int i = 0; i < NG_NETIF_NUMOF; i++) {
|
||||
if (ipv6_ifs[i].pid == pid) {
|
||||
return; /* prevent duplicates */
|
||||
}
|
||||
else if (ipv6_ifs[i].pid == KERNEL_PID_UNDEF) {
|
||||
ng_ipv6_addr_t addr = NG_IPV6_ADDR_ALL_NODES_LINK_LOCAL;
|
||||
mutex_lock(&ipv6_ifs[i].mutex);
|
||||
|
||||
DEBUG("Add IPv6 interface %" PRIkernel_pid " (i = %d)\n", pid, i);
|
||||
ipv6_ifs[i].pid = pid;
|
||||
DEBUG(" * pid = %" PRIkernel_pid "\n", ipv6_ifs[i].pid);
|
||||
ipv6_ifs[i].mtu = NG_IPV6_DEFAULT_MTU;
|
||||
DEBUG(" * mtu = %d\n", ipv6_ifs[i].mtu);
|
||||
|
||||
_add_addr_to_entry(&ipv6_ifs[i], &addr, 0);
|
||||
|
||||
mutex_unlock(&ipv6_ifs[i].mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("Could not add %" PRIkernel_pid " to IPv6: No space left.\n", pid);
|
||||
}
|
||||
|
||||
void ng_ipv6_netif_remove(kernel_pid_t pid)
|
||||
{
|
||||
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
|
||||
|
||||
if (entry == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&entry->mutex);
|
||||
|
||||
_reset_addr_from_entry(entry);
|
||||
DEBUG("Remove IPv6 interface %" PRIkernel_pid "\n", pid);
|
||||
entry->pid = KERNEL_PID_UNDEF;
|
||||
|
||||
mutex_unlock(&entry->mutex);
|
||||
}
|
||||
|
||||
ng_ipv6_netif_t *ng_ipv6_netif_get(kernel_pid_t pid)
|
||||
{
|
||||
for (int i = 0; i < NG_NETIF_NUMOF; i++) {
|
||||
if (ipv6_ifs[i].pid == pid) {
|
||||
DEBUG("Get IPv6 interface %" PRIkernel_pid " (%p, i = %d)\n", pid,
|
||||
(void *)(&(ipv6_ifs[i])), i);
|
||||
return &(ipv6_ifs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ng_ipv6_netif_add_addr(kernel_pid_t pid, const ng_ipv6_addr_t *addr,
|
||||
bool anycast)
|
||||
{
|
||||
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
|
||||
int res;
|
||||
|
||||
if (entry == NULL) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if ((addr == NULL) || (ng_ipv6_addr_is_unspecified(addr))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&entry->mutex);
|
||||
|
||||
res = _add_addr_to_entry(entry, addr, anycast);
|
||||
|
||||
mutex_unlock(&entry->mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void ng_ipv6_netif_remove_addr(kernel_pid_t pid, ng_ipv6_addr_t *addr)
|
||||
{
|
||||
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
|
||||
|
||||
if (entry == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&entry->mutex);
|
||||
|
||||
for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
|
||||
if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
|
||||
DEBUG("Remove %s to interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), pid);
|
||||
ng_ipv6_addr_set_unspecified(&(entry->addrs[i].addr));
|
||||
entry->addrs[i].flags = 0;
|
||||
|
||||
mutex_unlock(&entry->mutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&entry->mutex);
|
||||
}
|
||||
|
||||
void ng_ipv6_netif_reset_addr(kernel_pid_t pid)
|
||||
{
|
||||
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
|
||||
|
||||
if (entry == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&entry->mutex);
|
||||
|
||||
_reset_addr_from_entry(entry);
|
||||
|
||||
mutex_unlock(&entry->mutex);
|
||||
}
|
||||
|
||||
kernel_pid_t ng_ipv6_netif_find_by_addr(ng_ipv6_addr_t **out, const ng_ipv6_addr_t *addr)
|
||||
{
|
||||
for (int i = 0; i < NG_NETIF_NUMOF; i++) {
|
||||
if (out != NULL) {
|
||||
*out = ng_ipv6_netif_find_addr(ipv6_ifs[i].pid, addr);
|
||||
|
||||
if (*out != NULL) {
|
||||
DEBUG("Found %s on interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, *out, sizeof(addr_str)),
|
||||
ipv6_ifs[i].pid);
|
||||
return ipv6_ifs[i].pid;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ng_ipv6_netif_find_addr(ipv6_ifs[i].pid, addr) != NULL) {
|
||||
DEBUG("Found %s on interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, *out, sizeof(addr_str)),
|
||||
ipv6_ifs[i].pid);
|
||||
return ipv6_ifs[i].pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (out != NULL) {
|
||||
*out = NULL;
|
||||
}
|
||||
|
||||
return KERNEL_PID_UNDEF;
|
||||
}
|
||||
|
||||
ng_ipv6_addr_t *ng_ipv6_netif_find_addr(kernel_pid_t pid, const ng_ipv6_addr_t *addr)
|
||||
{
|
||||
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
|
||||
|
||||
if (entry == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mutex_lock(&entry->mutex);
|
||||
|
||||
for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
|
||||
if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
|
||||
mutex_unlock(&entry->mutex);
|
||||
DEBUG("Found %s on interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
pid);
|
||||
return &(entry->addrs[i].addr);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&entry->mutex);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t _find_by_prefix_unsafe(ng_ipv6_addr_t **res, ng_ipv6_netif_t *iface,
|
||||
const ng_ipv6_addr_t *addr, bool only_unicast)
|
||||
{
|
||||
uint8_t best_match = 0;
|
||||
|
||||
for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
|
||||
uint8_t match;
|
||||
|
||||
if ((only_unicast &&
|
||||
ng_ipv6_netif_addr_is_non_unicast(&(iface->addrs[i].addr))) ||
|
||||
ng_ipv6_addr_is_unspecified(&(iface->addrs[i].addr))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
match = ng_ipv6_addr_match_prefix(&(iface->addrs[i].addr), addr);
|
||||
|
||||
if (match > best_match) {
|
||||
if (res != NULL) {
|
||||
*res = &(iface->addrs[i].addr);
|
||||
}
|
||||
|
||||
best_match = match;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
|
||||
if (*res != NULL) {
|
||||
DEBUG("Found %s on interface %" PRIkernel_pid " matching ",
|
||||
ng_ipv6_addr_to_str(addr_str, *res, sizeof(addr_str)),
|
||||
iface->pid);
|
||||
DEBUG("%s by %" PRIu8 " bits (used as source address = %s)\n",
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
best_match,
|
||||
(only_unicast) ? "true" : "false");
|
||||
}
|
||||
else {
|
||||
DEBUG("Did not found any address on interface %" PRIkernel_pid
|
||||
" matching %s (used as source address = %s)\n",
|
||||
iface->pid,
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
(only_unicast) ? "true" : "false");
|
||||
}
|
||||
|
||||
#endif
|
||||
return best_match;
|
||||
}
|
||||
|
||||
kernel_pid_t ng_ipv6_netif_find_by_prefix(ng_ipv6_addr_t **out, const ng_ipv6_addr_t *prefix)
|
||||
{
|
||||
uint8_t best_match = 0;
|
||||
ng_ipv6_addr_t *tmp_res = NULL;
|
||||
kernel_pid_t res = KERNEL_PID_UNDEF;
|
||||
|
||||
for (int i = 0; i < NG_NETIF_NUMOF; i++) {
|
||||
uint8_t match;
|
||||
|
||||
mutex_lock(&(ipv6_ifs[i].mutex));
|
||||
|
||||
match = _find_by_prefix_unsafe(&tmp_res, ipv6_ifs + i, prefix, false);
|
||||
|
||||
if (match > best_match) {
|
||||
if (out != NULL) {
|
||||
*out = tmp_res;
|
||||
}
|
||||
|
||||
res = ipv6_ifs[i].pid;
|
||||
best_match = match;
|
||||
}
|
||||
|
||||
mutex_unlock(&(ipv6_ifs[i].mutex));
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
|
||||
if (res != KERNEL_PID_UNDEF) {
|
||||
DEBUG("Found %s on interface %" PRIkernel_pid " globally matching ",
|
||||
ng_ipv6_addr_to_str(addr_str, *out, sizeof(addr_str)),
|
||||
res);
|
||||
DEBUG("%s by %" PRIu8 " bits\n",
|
||||
ng_ipv6_addr_to_str(addr_str, prefix, sizeof(addr_str)),
|
||||
best_match);
|
||||
}
|
||||
else {
|
||||
DEBUG("Did not found any address globally matching %s\n",
|
||||
ng_ipv6_addr_to_str(addr_str, prefix, sizeof(addr_str)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static ng_ipv6_addr_t *_match_prefix(kernel_pid_t pid, const ng_ipv6_addr_t *addr,
|
||||
bool only_unicast)
|
||||
{
|
||||
ng_ipv6_addr_t *res = NULL;
|
||||
ng_ipv6_netif_t *iface = ng_ipv6_netif_get(pid);
|
||||
|
||||
mutex_lock(&(iface->mutex));
|
||||
|
||||
if (_find_by_prefix_unsafe(&res, iface, addr, only_unicast) > 0) {
|
||||
mutex_unlock(&(iface->mutex));
|
||||
return res;
|
||||
}
|
||||
|
||||
mutex_unlock(&(iface->mutex));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ng_ipv6_addr_t *ng_ipv6_netif_match_prefix(kernel_pid_t pid,
|
||||
const ng_ipv6_addr_t *prefix)
|
||||
{
|
||||
return _match_prefix(pid, prefix, false);
|
||||
}
|
||||
|
||||
ng_ipv6_addr_t *ng_ipv6_netif_find_best_src_addr(kernel_pid_t pid, const ng_ipv6_addr_t *dest)
|
||||
{
|
||||
return _match_prefix(pid, dest, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
Loading…
Reference in New Issue
Block a user