Skip to content

Commit

Permalink
[SQUASH ME] ipv6.if: tests and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
miri64 committed Nov 14, 2014
1 parent e7ae45a commit 4776a3e
Show file tree
Hide file tree
Showing 6 changed files with 467 additions and 23 deletions.
47 changes: 31 additions & 16 deletions sys/net/include/ipv6/if.h
Expand Up @@ -56,7 +56,7 @@ extern "C" {
/**
* @brief ID of the loopback interface.
*/
#define IPV6_IF_LOOPBACK_IF (IPV6_IF_NUM)
#define IPV6_IF_LOOPBACK_ID (IPV6_IF_NUM)

/**
* @brief Flags and scope for an address registered to and interface
Expand All @@ -65,8 +65,7 @@ extern "C" {
* RFC 4291
* </a>
*/
typedef enum __attribute__((packed))
{
typedef enum __attribute__((packed)) {
/**
* @brief Identifies address as a unicast address.
*
Expand Down Expand Up @@ -96,8 +95,7 @@ typedef enum __attribute__((packed))
* @brief Identifies address as a link-local address.
*/
IPV6_IF_ADDR_FLAGS_LINK_LOCAL = 0x04
}
ipv6_if_addr_flags_t;
} ipv6_if_addr_flags_t;

/**
* @brief Type to represent an address registered to an interface
Expand Down Expand Up @@ -138,6 +136,8 @@ typedef struct {

extern ipv6_if_t ipv6_ifs[IPV6_IF_NUM];

extern const ipv6_if_t ipv6_if_loopback;

/**
* @brief Initializes the module.
*/
Expand All @@ -149,6 +149,8 @@ void ipv6_if_init(void);
* @param[in] mac_pid A MAC layer's PID
*
* @return The new interface's ID on success.
* @return -EINVAL if *mac_pid* is KERNEL_PID_UNDEF
* @return -EISCONN if *mac_pid* is already connected to the interface
* @return -ENOBUFS if no space for a new interface is left.
*/
int ipv6_if_init_if(kernel_pid_t mac_pid);
Expand All @@ -170,8 +172,8 @@ void ipv6_if_reset_if(int if_id);
*/
static inline bool ipv6_if_initialized(int if_id)
{
return (if_id >= 0) && (if_id < IPV6_IF_NUM) &&
(ipv6_ifs[if_id].mac_pid != KERNEL_PID_UNDEF);
return (if_id == IPV6_IF_LOOPBACK_ID) ||
((if_id >= 0) && (if_id < IPV6_IF_NUM) && (ipv6_ifs[if_id].mac_pid != KERNEL_PID_UNDEF));
}

/**
Expand All @@ -184,7 +186,15 @@ static inline bool ipv6_if_initialized(int if_id)
*/
static inline ipv6_if_t *ipv6_if_get_by_id(int if_id)
{
return (ipv6_if_initialized(if_id)) ? (&(ipv6_ifs[if_id])) : NULL;
if (if_id == IPV6_IF_LOOPBACK_ID) {
return (ipv6_if_t *)(&ipv6_if_loopback);
}
else if (ipv6_if_initialized(if_id)) {
return &(ipv6_ifs[if_id]);
}
else {
return NULL;
}
}

/**
Expand Down Expand Up @@ -214,9 +224,7 @@ static inline ipv6_if_t *ipv6_if_get_by_mac(kernel_pid_t mac_pid)
/**
* @brief Adds an address to an interface
*
* @param[in] if_id An interface's ID
* @param[in] addr An IPv6 address
* @param[in] anycast Identifies *addr* as anycast address if true.
* @details Duplicate addresses are ignored
*
* @see <a href="https://tools.ietf.org/html/rfc4291#section-2.6">
* RFC 4291, section 2.6
Expand All @@ -225,6 +233,10 @@ static inline ipv6_if_t *ipv6_if_get_by_mac(kernel_pid_t mac_pid)
* RFC 4291, section 2.5
* </a> on address syntax.
*
* @param[in] if_id An interface's ID
* @param[in] addr An IPv6 address
* @param[in] anycast Identifies *addr* as anycast address if true.
*
* @return 0, on success
* @return -EINVAL, if *addr* is syntactically no unicast address, but *anycast*
* is set or if *addr* is the unspecified or loopback address.
Expand Down Expand Up @@ -252,7 +264,9 @@ int ipv6_if_rem_addr(int if_id, const ipv6_addr_t *addr);
* @param[in] addr An IPv6 address
*
* @return Pointer to the address on the interface, if it is is registered
* @return NULL, if the address is not registered to this interface
* @return NULL, if the address is not registered to this interface or if
* there is no interface identified by *if_id*
*/
ipv6_addr_t *ipv6_if_find_addr_on_if(int if_id, const ipv6_addr_t *addr);

Expand All @@ -277,8 +291,8 @@ ipv6_if_addr_search_res_t *ipv6_if_find_addr(ipv6_if_addr_search_res_t *res,
* @param[in] addr An IPv6 address
*
* @return Pointer to the found address on the interface, if it is is registered
* @return NULL, if there is no address registered to this interface or on
* error
* @return NULL, if there is no address registered to this interface or if
* there is no interface identified by *if_id*
*/
ipv6_addr_t *ipv6_if_find_prefix_match_on_if(int if_id, const ipv6_addr_t *addr);

Expand Down Expand Up @@ -310,8 +324,9 @@ ipv6_if_addr_search_res_t *ipv6_if_find_prefix_match(ipv6_if_addr_search_res_t *
* @param[in] addr A destination address for a packet we search the source
* address for.
*
* @return The best source address for the interface, on success
* @return NULL, if no suitable address could be found.
* @return The best source address for the interface, on success
* @return NULL, if no suitable address could be found or if there is no
* interface identified by *if_id*.
*/
ipv6_addr_t *ipv6_if_get_best_src_addr_on_if(int if_id, const ipv6_addr_t *addr);

Expand Down
34 changes: 27 additions & 7 deletions sys/net/network_layer/ipv6/if/if.c
Expand Up @@ -21,15 +21,16 @@
#include "ipv6/if.h"

#define _CHECK(if_id, err_ret) \
if (ipv6_if_initialized(if_id)) { \
if (!ipv6_if_initialized(if_id)) { \
err_ret; \
};

ipv6_if_t ipv6_ifs[IPV6_IF_NUM];

static const ipv6_if_addr_t _loopback = {
IPV6_ADDR_LOOPBACK,
IPV6_IF_ADDR_FLAGS_UNICAST
const ipv6_if_t ipv6_if_loopback = {
{ { IPV6_ADDR_LOOPBACK, IPV6_IF_ADDR_FLAGS_UNICAST } },
MUTEX_INIT,
KERNEL_PID_UNDEF,
};

static inline void _reset_addr(ipv6_if_addr_t *a)
Expand Down Expand Up @@ -62,7 +63,15 @@ void ipv6_if_init(void)

int ipv6_if_init_if(kernel_pid_t mac_pid)
{
if(mac_pid == KERNEL_PID_UNDEF) {
return -EINVAL;
}

for (int if_id = 0; if_id < IPV6_IF_NUM; if_id++) {
if (ipv6_ifs[if_id].mac_pid == mac_pid) {
return -EISCONN;
}

if (ipv6_ifs[if_id].mac_pid == KERNEL_PID_UNDEF) {
mutex_lock(&(ipv6_ifs[if_id].mutex));

Expand Down Expand Up @@ -106,6 +115,8 @@ int ipv6_if_get_id_by_mac(kernel_pid_t mac_pid)

int ipv6_if_add_addr(int if_id, const ipv6_addr_t *addr, bool anycast)
{
int res = -ENOBUFS;

_CHECK(if_id, return -ENOENT);

if (ipv6_addr_is_unspecified(addr) || ipv6_addr_is_loopback(addr) ||
Expand All @@ -131,12 +142,21 @@ int ipv6_if_add_addr(int if_id, const ipv6_addr_t *addr, bool anycast)
if (ipv6_addr_is_link_local(addr)) {
ipv6_ifs[if_id].addrs[i].flags |= IPV6_IF_ADDR_FLAGS_LINK_LOCAL;
}

res = 0;

break;
}
else if (ipv6_addr_is_equal(&(ipv6_ifs[if_id].addrs[i].addr), addr)) {
res = 0;

break;
}
}

mutex_unlock(&(ipv6_ifs[if_id].mutex));

return -ENOBUFS;
return res;
}

static ipv6_addr_t *_ipv6_if_find_addr_on_if(ipv6_if_t *ipv6_if,
Expand Down Expand Up @@ -194,8 +214,8 @@ ipv6_if_addr_search_res_t *ipv6_if_find_addr(ipv6_if_addr_search_res_t *res,
}

if (ipv6_addr_is_loopback(addr)) {
res->if_id = IPV6_IF_LOOPBACK_IF;
res->addr = (ipv6_addr_t *)&_loopback.addr; /* _loopback is const */
res->if_id = IPV6_IF_LOOPBACK_ID;
res->addr = (ipv6_addr_t *)&ipv6_if_loopback.addrs[0].addr; /* ipv6_if_loopback is const */

return res;
}
Expand Down
3 changes: 3 additions & 0 deletions tests/unittests/tests-ipv6_if/Makefile
@@ -0,0 +1,3 @@
MODULE = tests-ipv6_if

include $(RIOTBASE)/Makefile.base
1 change: 1 addition & 0 deletions tests/unittests/tests-ipv6_if/Makefile.include
@@ -0,0 +1 @@
USEMODULE += ipv6_if

0 comments on commit 4776a3e

Please sign in to comment.