1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

ipv6_netif: prepare for NDP

This commit is contained in:
Martine Lenders 2015-05-03 13:46:18 +02:00
parent 856c951d40
commit 70d7fae538
2 changed files with 173 additions and 55 deletions

View File

@ -29,6 +29,7 @@
#include "kernel_types.h" #include "kernel_types.h"
#include "mutex.h" #include "mutex.h"
#include "net/ng_ipv6/addr.h" #include "net/ng_ipv6/addr.h"
#include "vtimer.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -79,6 +80,24 @@ extern "C" {
*/ */
#define NG_IPV6_NETIF_ADDR_FLAGS_UNICAST (0x00) /**< unicast address */ #define NG_IPV6_NETIF_ADDR_FLAGS_UNICAST (0x00) /**< unicast address */
#define NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST (0x01) /**< non-unicast address */ #define NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST (0x01) /**< non-unicast address */
/**
* @brief A prefix information option that propagates the prefix of this
* address should set the autonomous flag.
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.1">
* RFC 4861, section 6.2.1
* </a>
*/
#define NG_IPV6_NETIF_ADDR_FLAGS_NDP_AUTO (0x40)
/**
* @brief A prefix information option that propagates the prefix of this
* address should set the on-link flag.
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.1">
* RFC 4861, section 6.2.1
* </a>
*/
#define NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK (0x80)
/** /**
* @} * @}
*/ */
@ -87,7 +106,45 @@ extern "C" {
* @{ * @{
* @name Flags for the interfaces * @name Flags for the interfaces
*/ */
#define NG_IPV6_NETIF_FLAGS_SIXLOWPAN (0x01) /**< interface is 6LoWPAN interface */ /**
* @brief Interface is 6LoWPAN interface.
*/
#define NG_IPV6_NETIF_FLAGS_SIXLOWPAN (0x0001)
/**
* @brief Flag to indicate that routing is enabled on the interface.
*/
#define NG_IPV6_NETIF_FLAGS_ROUTER (0x0002)
/**
* @brief Flag to indicate that the interface sends periodic router
* advertisements and in response to router solicitations.
*/
#define NG_IPV6_NETIF_FLAGS_RTR_ADV (0x0004)
/**
* @brief Flag to indicate that ng_ipv6_netif_t::mtu shall be propagated
* with the MTU options in router advertisements.
*/
#define NG_IPV6_NETIF_FLAGS_ADV_MTU (0x0008)
/**
* @brief Flag to indicate that ng_ipv6_netif_t::cur_hl shall be propagated
* in router advertisements.
*/
#define NG_IPV6_NETIF_FLAGS_ADV_CUR_HL (0x0010)
/**
* @brief Flag to indicate that the interface has other address
* configuration.
*/
#define NG_IPV6_NETIF_FLAGS_OTHER_CONF (0x4000)
/**
* @brief Flag to indicate that the interface has managed address
* configuration (e.g. via DHCPv6).
*/
#define NG_IPV6_NETIF_FLAGS_MANAGED (0x8000)
/** /**
* @} * @}
*/ */
@ -99,6 +156,32 @@ typedef struct {
ng_ipv6_addr_t addr; /**< The address data */ ng_ipv6_addr_t addr; /**< The address data */
uint8_t flags; /**< flags */ uint8_t flags; /**< flags */
uint8_t prefix_len; /**< length of the prefix of the address */ uint8_t prefix_len; /**< length of the prefix of the address */
/**
* @{
* @name Neigbour discovery variables for prefixes
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.1">
* RFC 4861, section 6.2.1
* </a>
*/
/**
* @brief The time in seconds this address is valid. If it is UINT32_MAX
* the lifetime is infinite.
*/
uint32_t valid;
/**
* @brief The length of time that this address remains preferred.
* If it is UINT32_MAX the lifetime is infinite.
* It **must** be < ng_ipv6_netif_addr_t::valid.
*/
uint32_t preferred;
/**
* @brief Validity timeout timer.
*/
vtimer_t valid_timeout;
/**
* @}
*/
} ng_ipv6_netif_addr_t; } ng_ipv6_netif_addr_t;
/** /**
@ -111,7 +194,7 @@ typedef struct {
kernel_pid_t pid; /**< PID of the interface */ kernel_pid_t pid; /**< PID of the interface */
uint16_t mtu; /**< Maximum Transmission Unit (MTU) of the interface */ uint16_t mtu; /**< Maximum Transmission Unit (MTU) of the interface */
uint8_t cur_hl; /**< current hop limit for the interface */ uint8_t cur_hl; /**< current hop limit for the interface */
uint8_t flags; /**< flags for 6LoWPAN and Neighbor Discovery */ uint16_t flags; /**< flags for 6LoWPAN and Neighbor Discovery */
} ng_ipv6_netif_t; } ng_ipv6_netif_t;
/** /**
@ -154,28 +237,29 @@ ng_ipv6_netif_t *ng_ipv6_netif_get(kernel_pid_t pid);
* @param[in] addr An address you want to add to the interface. * @param[in] addr An address you want to add to the interface.
* @param[in] prefix_len Length of the prefix of the address. * @param[in] prefix_len Length of the prefix of the address.
* Must be between 1 and 128. * Must be between 1 and 128.
* @param[in] anycast If @p addr should be an anycast address, @p anycast * @param[in] flags Flags for the address entry
* must be true. Otherwise set it false. * If @p addr should be an anycast address, @p flags
* If @p addr is a multicast address, @p anycast will be * must have @ref NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST
* ignored. * set. Otherwise leave it unset.
* If @p addr is a multicast address, the status of
* @ref NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST will be
* ignored and set in either case.
* *
* @see <a href="https://tools.ietf.org/html/rfc4291#section-2.6"> * @see <a href="https://tools.ietf.org/html/rfc4291#section-2.6">
* RFC 4291, section 2.6 * RFC 4291, section 2.6
* </a> * </a>
* *
* @return 0, on success. * @return The address on the interface, on success.
* @return -EINVAL, if @p addr is NULL or unspecified address or if * @return NULL, on failure
* @p prefix length was < 1 or > 128.
* @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, ng_ipv6_addr_t *ng_ipv6_netif_add_addr(kernel_pid_t pid, const ng_ipv6_addr_t *addr,
uint8_t prefix_len, bool anycast); uint8_t prefix_len, uint8_t flags);
/** /**
* @brief Remove an address from the interface. * @brief Remove an address from the interface.
* *
* @param[in] pid The PID to the interface. * @param[in] pid The PID to the interface. If @p pid is KERNEL_PID_UNDEF
* it will be removed from all interfaces.
* @param[in] addr An address you want to remove from 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); void ng_ipv6_netif_remove_addr(kernel_pid_t pid, ng_ipv6_addr_t *addr);
@ -254,12 +338,37 @@ ng_ipv6_addr_t *ng_ipv6_netif_match_prefix(kernel_pid_t pid,
*/ */
ng_ipv6_addr_t *ng_ipv6_netif_find_best_src_addr(kernel_pid_t pid, const ng_ipv6_addr_t *dest); ng_ipv6_addr_t *ng_ipv6_netif_find_best_src_addr(kernel_pid_t pid, const ng_ipv6_addr_t *dest);
/**
* @brief Get interface specific meta-information on an address
*
* @details This only works with addresses you retrieved via the following
* functions:
*
* * ng_ipv6_netif_add_addr()
* * 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 get the meta-information for.
*
* @return Interface specific meta-information on @p addr
*/
static inline ng_ipv6_netif_addr_t *ng_ipv6_netif_addr_get(const ng_ipv6_addr_t *addr)
{
return container_of(addr, ng_ipv6_netif_addr_t, addr);
}
/** /**
* @brief Checks if an address is non-unicast. * @brief Checks if an address is non-unicast.
* *
* @details This only works with addresses you retrieved via the following * @details This only works with addresses you retrieved via the following
* functions: * functions:
* *
* * ng_ipv6_netif_add_addr()
* * ng_ipv6_find_addr() * * ng_ipv6_find_addr()
* * ng_ipv6_find_addr_local() * * ng_ipv6_find_addr_local()
* * ng_ipv6_find_prefix_match() * * ng_ipv6_find_prefix_match()

View File

@ -20,7 +20,6 @@
#include "kernel_types.h" #include "kernel_types.h"
#include "mutex.h" #include "mutex.h"
#include "net/ng_ipv6.h"
#include "net/ng_ipv6/addr.h" #include "net/ng_ipv6/addr.h"
#include "net/ng_netif.h" #include "net/ng_netif.h"
@ -35,12 +34,12 @@ static ng_ipv6_netif_t ipv6_ifs[NG_NETIF_NUMOF];
static char addr_str[NG_IPV6_ADDR_MAX_STR_LEN]; static char addr_str[NG_IPV6_ADDR_MAX_STR_LEN];
#endif #endif
static int _add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr, static ng_ipv6_addr_t *_add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr,
uint8_t prefix_len, bool anycast) uint8_t prefix_len, uint8_t flags)
{ {
for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) { for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) { if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
return 0; return &(entry->addrs[i].addr);
} }
if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr))) { if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr))) {
@ -49,17 +48,14 @@ static int _add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
prefix_len, entry->pid); prefix_len, entry->pid);
if (anycast || ng_ipv6_addr_is_multicast(addr)) { entry->addrs[i].prefix_len = prefix_len;
if (ng_ipv6_addr_is_multicast(addr)) { entry->addrs[i].flags = flags;
entry->addrs[i].prefix_len = NG_IPV6_ADDR_BIT_LEN;
}
entry->addrs[i].flags = NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST; if (ng_ipv6_addr_is_multicast(addr)) {
entry->addrs[i].flags |= NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST;
return 0;
} }
else { else {
entry->addrs[i].prefix_len = prefix_len; ng_ipv6_addr_t sol_node;
if (!ng_ipv6_addr_is_link_local(addr)) { if (!ng_ipv6_addr_is_link_local(addr)) {
/* add also corresponding link-local address */ /* add also corresponding link-local address */
@ -68,17 +64,22 @@ static int _add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr
ll_addr.u64[1] = addr->u64[1]; ll_addr.u64[1] = addr->u64[1];
ng_ipv6_addr_set_link_local_prefix(&ll_addr); ng_ipv6_addr_set_link_local_prefix(&ll_addr);
entry->addrs[i].flags = NG_IPV6_NETIF_ADDR_FLAGS_UNICAST; _add_addr_to_entry(entry, &ll_addr, 64,
flags | NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK);
return _add_addr_to_entry(entry, &ll_addr, 64, false); }
else {
entry->addrs[i].flags |= NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK;
} }
return 0; ng_ipv6_addr_set_solicited_nodes(&sol_node, addr);
_add_addr_to_entry(entry, &sol_node, NG_IPV6_ADDR_BIT_LEN, 0);
} }
return &entry->addrs[i].addr;
} }
} }
return -ENOMEM; return NULL;
} }
static void _reset_addr_from_entry(ng_ipv6_netif_t *entry) static void _reset_addr_from_entry(ng_ipv6_netif_t *entry)
@ -110,16 +111,18 @@ void ng_ipv6_netif_add(kernel_pid_t pid)
DEBUG("Add IPv6 interface %" PRIkernel_pid " (i = %d)\n", pid, i); DEBUG("Add IPv6 interface %" PRIkernel_pid " (i = %d)\n", pid, i);
ipv6_ifs[i].pid = pid; ipv6_ifs[i].pid = pid;
DEBUG(" * pid = %" PRIkernel_pid " ", ipv6_ifs[i].pid);
ipv6_ifs[i].mtu = NG_IPV6_NETIF_DEFAULT_MTU; ipv6_ifs[i].mtu = NG_IPV6_NETIF_DEFAULT_MTU;
DEBUG("mtu = %d ", ipv6_ifs[i].mtu);
ipv6_ifs[i].cur_hl = NG_IPV6_NETIF_DEFAULT_HL; ipv6_ifs[i].cur_hl = NG_IPV6_NETIF_DEFAULT_HL;
DEBUG("cur_hl = %d ", ipv6_ifs[i].cur_hl); ipv6_ifs[i].flags = 0;
_add_addr_to_entry(&ipv6_ifs[i], &addr, NG_IPV6_ADDR_BIT_LEN, 0); _add_addr_to_entry(&ipv6_ifs[i], &addr, NG_IPV6_ADDR_BIT_LEN, 0);
mutex_unlock(&ipv6_ifs[i].mutex); mutex_unlock(&ipv6_ifs[i].mutex);
DEBUG(" * pid = %" PRIkernel_pid " ", ipv6_ifs[i].pid);
DEBUG("cur_hl = %d ", ipv6_ifs[i].cur_hl);
DEBUG("mtu = %d ", ipv6_ifs[i].mtu);
DEBUG("flags = %04" PRIx16 "\n", ipv6_ifs[i].flags);
return; return;
} }
} }
@ -140,6 +143,7 @@ void ng_ipv6_netif_remove(kernel_pid_t pid)
_reset_addr_from_entry(entry); _reset_addr_from_entry(entry);
DEBUG("Remove IPv6 interface %" PRIkernel_pid "\n", pid); DEBUG("Remove IPv6 interface %" PRIkernel_pid "\n", pid);
entry->pid = KERNEL_PID_UNDEF; entry->pid = KERNEL_PID_UNDEF;
entry->flags = 0;
mutex_unlock(&entry->mutex); mutex_unlock(&entry->mutex);
} }
@ -157,38 +161,28 @@ ng_ipv6_netif_t *ng_ipv6_netif_get(kernel_pid_t pid)
return NULL; return NULL;
} }
int ng_ipv6_netif_add_addr(kernel_pid_t pid, const ng_ipv6_addr_t *addr, ng_ipv6_addr_t *ng_ipv6_netif_add_addr(kernel_pid_t pid, const ng_ipv6_addr_t *addr,
uint8_t prefix_len, bool anycast) uint8_t prefix_len, uint8_t flags)
{ {
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid); ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
int res; ng_ipv6_addr_t *res;
if (entry == NULL) { if ((entry == NULL) || (addr == NULL) || (ng_ipv6_addr_is_unspecified(addr)) ||
return -ENOENT;
}
if ((addr == NULL) || (ng_ipv6_addr_is_unspecified(addr)) ||
((prefix_len - 1) > 127)) { /* prefix_len < 1 || prefix_len > 128 */ ((prefix_len - 1) > 127)) { /* prefix_len < 1 || prefix_len > 128 */
return -EINVAL; return NULL;
} }
mutex_lock(&entry->mutex); mutex_lock(&entry->mutex);
res = _add_addr_to_entry(entry, addr, prefix_len, anycast); res = _add_addr_to_entry(entry, addr, prefix_len, flags);
mutex_unlock(&entry->mutex); mutex_unlock(&entry->mutex);
return res; return res;
} }
void ng_ipv6_netif_remove_addr(kernel_pid_t pid, ng_ipv6_addr_t *addr) static void _remove_addr_from_entry(ng_ipv6_netif_t *entry, ng_ipv6_addr_t *addr)
{ {
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
if (entry == NULL) {
return;
}
mutex_lock(&entry->mutex); mutex_lock(&entry->mutex);
for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) { for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
@ -206,6 +200,24 @@ void ng_ipv6_netif_remove_addr(kernel_pid_t pid, ng_ipv6_addr_t *addr)
mutex_unlock(&entry->mutex); mutex_unlock(&entry->mutex);
} }
void ng_ipv6_netif_remove_addr(kernel_pid_t pid, ng_ipv6_addr_t *addr)
{
if (pid == KERNEL_PID_UNDEF) {
for (int i = 0; i < NG_NETIF_NUMOF; i++) {
if (ipv6_ifs[i].pid == KERNEL_PID_UNDEF) {
continue;
}
_remove_addr_from_entry(ipv6_ifs + i, addr);
}
}
else {
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
_remove_addr_from_entry(entry, addr);
}
}
void ng_ipv6_netif_reset_addr(kernel_pid_t pid) void ng_ipv6_netif_reset_addr(kernel_pid_t pid)
{ {
ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid); ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);
@ -307,7 +319,6 @@ static uint8_t _find_by_prefix_unsafe(ng_ipv6_addr_t **res, ng_ipv6_netif_t *ifa
} }
#if ENABLE_DEBUG #if ENABLE_DEBUG
if (*res != NULL) { if (*res != NULL) {
DEBUG("Found %s on interface %" PRIkernel_pid " matching ", DEBUG("Found %s on interface %" PRIkernel_pid " matching ",
ng_ipv6_addr_to_str(addr_str, *res, sizeof(addr_str)), ng_ipv6_addr_to_str(addr_str, *res, sizeof(addr_str)),
@ -324,8 +335,8 @@ static uint8_t _find_by_prefix_unsafe(ng_ipv6_addr_t **res, ng_ipv6_netif_t *ifa
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
(only_unicast) ? "true" : "false"); (only_unicast) ? "true" : "false");
} }
#endif #endif
return best_match; return best_match;
} }
@ -355,7 +366,6 @@ kernel_pid_t ng_ipv6_netif_find_by_prefix(ng_ipv6_addr_t **out, const ng_ipv6_ad
} }
#if ENABLE_DEBUG #if ENABLE_DEBUG
if (res != KERNEL_PID_UNDEF) { if (res != KERNEL_PID_UNDEF) {
DEBUG("Found %s on interface %" PRIkernel_pid " globally matching ", DEBUG("Found %s on interface %" PRIkernel_pid " globally matching ",
ng_ipv6_addr_to_str(addr_str, *out, sizeof(addr_str)), ng_ipv6_addr_to_str(addr_str, *out, sizeof(addr_str)),
@ -368,7 +378,6 @@ kernel_pid_t ng_ipv6_netif_find_by_prefix(ng_ipv6_addr_t **out, const ng_ipv6_ad
DEBUG("Did not found any address globally matching %s\n", DEBUG("Did not found any address globally matching %s\n",
ng_ipv6_addr_to_str(addr_str, prefix, sizeof(addr_str))); ng_ipv6_addr_to_str(addr_str, prefix, sizeof(addr_str)));
} }
#endif #endif
return res; return res;