/* * Copyright (C) 2015 Martine Lenders * * 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_gnrc_ipv6 IPv6 * @ingroup net_gnrc * @brief GNRC's IPv6 implementation * * This module is for usage with the @ref net_gnrc_netapi * * # Supported NETAPI commands * * This module handles the following @ref net_gnrc_netapi message types: * * ## `GNRC_NETAPI_MSG_TYPE_RCV` * * @ref GNRC_NETAPI_MSG_TYPE_RCV expects a @ref net_gnrc_pkt (referred to as * "packet" in the following) in receive order (payload first, headers ordered * down the stack). It must at least contain a link-layer payload starting * with a valid @ref net_ipv6_hdr. If it contains a @ref net_gnrc_netif_hdr this * header will be taken into account. * * If the link-layer payload is not an IPv6 packet (starting with a 0x6 * half-byte) or the module is not able to parse it correctly it will be * dropped. If the packet can't be forwarded (either to another node or an upper * layer) it will be dropped. Otherwise, there are two scenarios of success: * * 1. If the destination address is an address on this host, and a suitable * upper layer is registered the packet will be forwarded to that upper * layer. An upper layer is suitable with its registration if * * - it is registered with a tuple (@ref GNRC_NETTYPE_IPV6, `nh`), or * - it is registered with a tuple (@ref gnrc_nettype_from_protnum(`nh`), * @ref GNRC_NETREG_DEMUX_CTX_ALL). * * In both cases `nh` is the [next header field of one of the IPv6 header] * (@ref ipv6_hdr_t::nh) or the [next header field of one of the IPv6 * extension headers](@ref ipv6_ext_t::nh) within the packet. The IPv6 header * and every IPv6 extension header between the IPv6 header and the payload * will be marked as separate @ref gnrc_pktsnip_t (i.e. the IPv6 payload will * be the first snip due to receive order). Note, that IPv6-internal headers * (such as ICMPv6 and extension headers) are handled within this module. If * the [`gnrc_ipv6_ext`](@ref net_gnrc_ipv6_ext) module is not present, IPv6 * extension headers can't be parsed, so the packet might not be read * properly. * 2. If the receiving network interface (indicated by the * gnrc_netif_hdr_t::if_pid if provided or the destination address in the * IPv6 header) is configured as a forwarding interface, the destination is * not an address on this host, and a route is configured for the destination * the packet will be forwarded. In consequence, the module will emit a * @ref GNRC_NETAPI_MSG_TYPE_SND with the packet reversed into send order and * the (if necessary prepended) gnrc_netif_hdr_t::if_pid has the appropriate * link-layer destination addresses to the next hop towards the destination. * * ## `GNRC_NETAPI_MSG_TYPE_SND` * * @ref GNRC_NETAPI_MSG_TYPE_SND expects a @ref net_gnrc_pkt (referred to as * "packet" in the following) in send order (headers ordered up the stack, * payload last). It must at least contain a snip of type @ref GNRC_NETTYPE_IPV6 * as its first or second snip. If the first snip is not of type * @ref GNRC_NETTYPE_IPV6, it must be of type @ref GNRC_NETTYPE_NETIF. * * If the destination address within the @ref GNRC_NETTYPE_IPV6 snip is an * address on this host or the loopback address `::1`, the packet will be * [reversed](@ref gnrc_pktbuf_reverse_snips()) and * [merged](@ref gnrc_pktbuf_merge()) so that it has a format as though it came * from a network interface. It will then be handled as a received packet * ("looped back") by the IPv6 module (see previous section). * * Otherwise, if a route (or neighbor cache entry) to the IPv6 destination * address exists, the IPv6 header will be filled for fields that were not set * by upper layers and handed over to the link-layer (L2) with the L2 * destination address set to the L2 address associated to that IPv6 destination * address. * * ## `GNRC_NETAPI_MSG_TYPE_SET` * * `GNRC_NETAPI_MSG_TYPE_SET` is not supported. * * ## `GNRC_NETAPI_MSG_TYPE_GET` * * `GNRC_NETAPI_MSG_TYPE_GET` is not supported. * * @{ * * @file * @brief Definitions for GNRC's IPv6 implementation * * @author Martine Lenders * @author Oliver Hahm */ #ifndef NET_GNRC_IPV6_H #define NET_GNRC_IPV6_H #include "sched.h" #include "thread.h" #include "net/ipv6.h" #include "net/gnrc/ipv6/ext.h" #include "net/gnrc/ipv6/hdr.h" #include "net/gnrc/ipv6/nib.h" #ifdef MODULE_FIB #include "net/fib.h" #endif #ifdef __cplusplus extern "C" { #endif /** * @defgroup net_gnrc_ipv6_conf GNRC IPv6 compile configurations * @ingroup net_gnrc_ipv6 * @ingroup net_gnrc_conf * @{ */ /** * @brief Default stack size to use for the IPv6 thread */ #ifndef GNRC_IPV6_STACK_SIZE #define GNRC_IPV6_STACK_SIZE (THREAD_STACKSIZE_DEFAULT) #endif /** * @brief Default priority for the IPv6 thread */ #ifndef GNRC_IPV6_PRIO #define GNRC_IPV6_PRIO (THREAD_PRIORITY_MAIN - 3) #endif /** * @brief Default message queue size to use for the IPv6 thread (as exponent * of 2^n). * * As the queue size ALWAYS needs to be power of two, this option * represents the exponent of 2^n, which will be used as the size of * the queue. */ #ifndef CONFIG_GNRC_IPV6_MSG_QUEUE_SIZE_EXP #define CONFIG_GNRC_IPV6_MSG_QUEUE_SIZE_EXP (3U) #endif #ifdef DOXYGEN /** * @brief Add a static IPv6 link local address to any network interface * * This macro allows to specify a certain link local IPv6 address to be assigned * to a network interface on startup, which might be handy for testing. * Note: a) a interface will keep its auto-generated link local address, too * b) the address is incremented by 1, if multiple interfaces are present * * To use the macro just add it to `CFLAGS` in the application's Makefile, like: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk} * IPV6_STATIC_LLADDR ?= '"fe80::cafe:cafe:cafe:1"' * CFLAGS += -DGNRC_IPV6_STATIC_LLADDR=$(STATIC_IPV6_LLADDR) * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define GNRC_IPV6_STATIC_LLADDR #endif /* DOXYGEN */ /** @} */ /** * @brief Message queue size to use for the IPv6 thread. */ #ifndef GNRC_IPV6_MSG_QUEUE_SIZE #define GNRC_IPV6_MSG_QUEUE_SIZE (1 << CONFIG_GNRC_IPV6_MSG_QUEUE_SIZE_EXP) #endif /** * @brief The PID to the IPv6 thread. * * @note Use @ref gnrc_ipv6_init() to initialize. **Do not set by hand**. * * @details This variable is preferred for IPv6 internal communication *only*. * Please use @ref net_gnrc_netreg for external communication. */ extern kernel_pid_t gnrc_ipv6_pid; #ifdef MODULE_FIB /** * @brief Maximum number of entries in the IPv6 FIB table. */ #ifndef GNRC_IPV6_FIB_TABLE_SIZE # ifdef MODULE_GNRC_RPL # define GNRC_IPV6_FIB_TABLE_SIZE (20) # else # define GNRC_IPV6_FIB_TABLE_SIZE (5) # endif #endif /** * @brief The forwarding information base (FIB) for the IPv6 stack. * * @see @ref net_fib */ extern fib_table_t gnrc_ipv6_fib_table; #endif /** * @brief Initialization of the IPv6 thread. * * @return The PID to the IPv6 thread, on success. * @return a negative errno on error. * @return -EOVERFLOW, if there are too many threads running already * @return -EEXIST, if IPv6 was already initialized. */ kernel_pid_t gnrc_ipv6_init(void); /** * @brief Get the IPv6 header from a given list of @ref gnrc_pktsnip_t * * This function may be used with e.g. a pointer to a (full) UDP datagram. * * @pre Any @ref GNRC_NETTYPE_IPV6 snip in pkt is contains a full IPv6 header. * * @param[in] pkt The pointer to the first @ref gnrc_pktsnip_t of the * packet. * * @return A pointer to the @ref ipv6_hdr_t of the packet. * @return NULL if the packet does not contain an IPv6 header. */ ipv6_hdr_t *gnrc_ipv6_get_header(gnrc_pktsnip_t *pkt); #ifdef __cplusplus } #endif #endif /* NET_GNRC_IPV6_H */ /** * @} */