Skip to content

Commit

Permalink
Merge pull request #3049 from authmillenon/ng_ndp/feat/rtr-dscvry
Browse files Browse the repository at this point in the history
gnrc_ndp_router: Initial import of router behavior of router discovery
  • Loading branch information
miri64 committed Sep 2, 2015
2 parents 4fa3bb8 + 10e571d commit fc6896b
Show file tree
Hide file tree
Showing 12 changed files with 757 additions and 5 deletions.
8 changes: 7 additions & 1 deletion Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ endif
ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_router
USEMODULE += gnrc_icmpv6
USEMODULE += gnrc_ndp_node
USEMODULE += gnrc_ndp_router
endif

ifneq (,$(filter gnrc_ndp_host,$(USEMODULE)))
Expand All @@ -95,6 +95,12 @@ ifneq (,$(filter gnrc_ndp_host,$(USEMODULE)))
USEMODULE += vtimer
endif

ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
USEMODULE += gnrc_ndp_node
USEMODULE += random
USEMODULE += vtimer
endif

ifneq (,$(filter gnrc_ndp_node,$(USEMODULE)))
USEMODULE += gnrc_ndp_internal
endif
Expand Down
199 changes: 198 additions & 1 deletion sys/include/net/gnrc/ndp.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include "net/gnrc/ndp/host.h"
#include "net/gnrc/ndp/internal.h"
#include "net/gnrc/ndp/router.h"
#include "net/gnrc/ndp/node.h"

#ifdef __cplusplus
Expand All @@ -44,6 +45,8 @@ extern "C" {
#define GNRC_NDP_MSG_ADDR_TIMEOUT (0x0211) /**< Message type for address timeouts */
#define GNRC_NDP_MSG_NBR_SOL_RETRANS (0x0212) /**< Message type for multicast
* neighbor solicitation retransmissions */
#define GNRC_NDP_MSG_RTR_ADV_RETRANS (0x0213) /**< Message type for periodic router advertisements */
#define GNRC_NDP_MSG_RTR_ADV_DELAY (0x0214) /**< Message type for delayed router advertisements */
#define GNRC_NDP_MSG_RTR_SOL_RETRANS (0x0215) /**< Message type for periodic router solicitations */
#define GNRC_NDP_MSG_NC_STATE_TIMEOUT (0x0216) /**< Message type for neighbor cache state timeouts */

Expand Down Expand Up @@ -131,9 +134,43 @@ extern "C" {
* @brief Upper bound for randomised reachable time calculation.
*/
#define GNRC_NDP_MAX_RAND (15U)
/** @} */

/**
* @}
* @name Router constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc4861#section-10">
* RFC 4861, section 10
* </a>
*/
/**
* @brief Initial router advertisement interval in seconds
*/
#define GNRC_NDP_MAX_INIT_RTR_ADV_INT (16U)

/**
* @brief Maximum number of initial router advertisement transmissions
*/
#define GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF (3U)

/**
* @brief Maximum number of final router advertisement transmissions
*/
#define GNRC_NDP_MAX_FIN_RTR_ADV_NUMOF (3U)

/**
* @brief Minimum delay in seconds between router advertisement
* transmissions
*/
#define GNRC_NDP_MIN_RTR_ADV_DELAY (3U)

/**
* @brief Upper bound for randomised delay in microseconds between router
* solicitation reception and responding router advertisement
* transmission.
*/
#define GNRC_NDP_MAX_RTR_ADV_DELAY (500U * MS_IN_USEC)
/** @} */

/**
* @brief Handles received neighbor solicitations.
Expand Down Expand Up @@ -161,6 +198,32 @@ void gnrc_ndp_nbr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
ipv6_hdr_t *ipv6, ndp_nbr_adv_t *nbr_adv,
size_t icmpv6_size);

#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Handles received router solicitations.
*
* @param[in] iface The receiving interface.
* @param[in] pkt The received packet.
* @param[in] ipv6 The IPv6 header in @p pkt.
* @param[in] rtr_sol The router solicitation in @p pkt.
* @param[in] icmpv6_size The overall size of the router solicitation.
*/
void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
ipv6_hdr_t *ipv6, ndp_rtr_sol_t *rtr_sol,
size_t icmpv6_size);
#else
/**
* @brief A host *must* silently discard all received router solicitations.
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.6">
* RFC 4861, section 6.2.6
* </a>
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_rtr_sol_handle(iface, pkt, ipv6, rtr_sol, size)
#endif

/**
* @brief Handles received router advertisements
*
Expand Down Expand Up @@ -291,6 +354,65 @@ gnrc_pktsnip_t *gnrc_ndp_nbr_adv_build(uint8_t flags, ipv6_addr_t *tgt,
*/
gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options);

/**
* @brief Builds a router solicitation message for sending.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.1">
* RFC 4861, section 4.1
* </a>
*
* @param[in] options Options to append to the router solicitation.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, on failure.
*/
gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options);

#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Builds a router advertisement message for sending.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.2">
* RFC 4861, section 4.2
* </a>
*
* @note The source address for the packet MUST be the link-local address
* of the interface.
*
* @param[in] cur_hl Default hop limit for outgoing IP packets, 0 if
* unspecified by this router.
* @param[in] flags Flags as defined above.
* @ref GNRC_NDP_RTR_ADV_FLAGS_M == 1 indicates, that the
* addresses are managed by DHCPv6,
* @ref GNRC_NDP_RTR_ADV_FLAGS_O == 1 indicates that other
* configuration information is available via DHCPv6.
* @param[in] ltime Lifetime of the default router in seconds.
* @param[in] reach_time Time in milliseconds a node should assume a neighbor
* reachable. 0 means unspecified by the router.
* @param[in] retrans_timer Time in milliseconds between retransmitted
* neighbor solicitations. 0 means unspecified by
* the router.
* @param[in] options Options to append to the router advertisement.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, on failure.
*/
gnrc_pktsnip_t *gnrc_ndp_rtr_adv_build(uint8_t cur_hl, uint8_t flags, uint16_t ltime,
uint32_t reach_time, uint32_t retrans_timer,
gnrc_pktsnip_t *options);
#else
/**
* @brief A host *must not* send router advertisements at any time (so why build them?)
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
* RFC 4861, section 6.3.4
* </a>
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_rtr_adv_build(cur_hl, flags, ltime, reach_time, retrans_timer, options) (NULL)
#endif

/**
* @brief Builds a generic NDP option.
*
Expand Down Expand Up @@ -346,6 +468,81 @@ gnrc_pktsnip_t *gnrc_ndp_opt_sl2a_build(const uint8_t *l2addr, uint8_t l2addr_le
gnrc_pktsnip_t *gnrc_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len,
gnrc_pktsnip_t *next);

#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Builds the prefix information option.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.2">
* RFC 4861, section 4.6.2
* </a>
*
* @note Must only be used with router advertisemnents. This is not checked
* however, since nodes should silently ignore it in other NDP messages.
*
* @param[in] prefix_len The length of @p prefix in bits. Must be between
* 0 and 128.
* @param[in] flags Flags as defined above.
* @ref GNRC_NDP_OPT_PI_FLAGS_L == 1 indicates, that
* @p prefix can be used for on-link determination,
* @ref GNRC_NDP_OPT_PI_FLAGS_A == 1 indicates, that
* @p prefix can be used for stateless address
* configuration.
* @param[in] valid_ltime Length of time in seconds that @p prefix is valid.
* UINT32_MAX represents infinity.
* @param[in] pref_ltime Length of time in seconds that addresses using
* @p prefix remain prefered. UINT32_MAX represents
* infinity.
* @param[in] prefix An IPv6 address or a prefix of an IPv6 address.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp_opt_pi_build(uint8_t prefix_len, uint8_t flags,
uint32_t valid_ltime, uint32_t pref_ltime,
ipv6_addr_t *prefix, gnrc_pktsnip_t *next);

/**
* @brief Builds the MTU option.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.4">
* RFC 4861, section 4.6.4
* </a>
*
* @note Must only be used with router advertisemnents. This is not checked
* however, since nodes should silently ignore it in other NDP messages.
*
* @param[in] mtu The recommended MTU for the link.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next);
#else
/**
* @brief A host *must not* send router advertisements at any time (so why build their options?)
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
* RFC 4861, section 6.3.4
* </a>
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_opt_pi_build(prefix_len, flags, valid_ltime, pref_ltime, prefix, next) (NULL)

/**
* @brief A host *must not* send router advertisements at any time (so why build their options?)
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
* RFC 4861, section 6.3.4
* </a>
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_opt_mtu_build(mtu, next) (NULL)
#endif

#ifdef __cplusplus
}
#endif
Expand Down
24 changes: 24 additions & 0 deletions sys/include/net/gnrc/ndp/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,30 @@ void gnrc_ndp_internal_send_nbr_adv(kernel_pid_t iface, ipv6_addr_t *tgt, ipv6_a
*/
void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst);

#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Handles received router solicitations.
*
* @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF.
* @param[in] src Source address for the router advertisement. May be NULL to be determined
* by source address selection (:: if no @p iface has no address).
* @param[in] dst Destination address for router advertisement.
* @ref IPV6_ADDR_ALL_NODES_LINK_LOCAL if NULL.
* @param[in] fin This is part of the router's final batch of router advertisements
* before ceising to be a router (set's router lifetime field to 0).
*/
void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src,
ipv6_addr_t *dst, bool fin);
#else
/**
* @brief A host *must not* send router advertisements at any time.
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_internal_send_rtr_adv(iface, dst, fin)
#endif

/**
* @brief Handles a SL2A option.
*
Expand Down
88 changes: 88 additions & 0 deletions sys/include/net/gnrc/ndp/router.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (C) 2015 Martine Lenders <[email protected]>
*
* 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_ndp_router Router-specific part of router discovery.
* @ingroup net_gnrc_ndp
* @brief Router-specific part for the router discovery in IPv6
* neighbor discovery.
* @{
*
* @file
* @brief Router-specific router discovery definitions
*
* @author Martine Lenders <[email protected]>
*/
#ifndef GNRC_NDP_ROUTER_H_
#define GNRC_NDP_ROUTER_H_

#include <stdbool.h>

#include "kernel_types.h"
#include "net/ipv6/hdr.h"
#include "net/ndp.h"
#include "net/gnrc/ipv6/nc.h"
#include "timex.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Set @p iface to router mode.
*
* @details This sets/unsets the GNRC_IPV6_NETIF_FLAGS_ROUTER and
* GNRC_IPV6_NETIF_FLAGS_RTR_ADV and initializes or ceases router
* behavior for neighbor discovery.
*
* @param[in] iface An IPv6 interface. Must not be NULL.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_ROUTER and
* GNRC_IPV6_NETIF_FLAGS_RTR_ADV flags.
*/
void gnrc_ndp_router_set_router(gnrc_ipv6_netif_t *iface, bool enable);

/**
* @brief Set/Unset GNRC_IPV6_NETIF_FLAGS_RTR_ADV flag for @p iface.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.2">
* RFC 4861, section 6.2.2
* </a>
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.5">
* RFC 4861, section 6.2.5
* </a>
*
* @details GNRC_IPV6_NETIF_FLAGS_RTR_ADV and initializes or ceases
* periodic router advertising behavior for neighbor discovery.
*
* @param[in] iface An IPv6 interface. Must not be NULL.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_RTR_ADV flags.
*/
void gnrc_ndp_router_set_rtr_adv(gnrc_ipv6_netif_t *iface, bool enable);

/**
* @brief Send an unsolicited router advertisement over @p iface
* and reset the timer for the next one if necessary.
*
* @param[in] iface An IPv6 interface.
*/
void gnrc_ndp_router_retrans_rtr_adv(gnrc_ipv6_netif_t *iface);

/**
* @brief Send an solicited router advertisement to IPv6 address of
* @p neighbor.
*
* @param[in] neighbor A neighbor cache entry.
*/
void gnrc_ndp_router_send_rtr_adv(gnrc_ipv6_nc_t *neighbor);

#ifdef __cplusplus
}
#endif

#endif /* GNRC_NDP_ROUTER_H_ */
/** @} */
3 changes: 3 additions & 0 deletions sys/net/gnrc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ endif
ifneq (,$(filter gnrc_ndp_node,$(USEMODULE)))
DIRS += network_layer/ndp/node
endif
ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
DIRS += network_layer/ndp/router
endif
ifneq (,$(filter gnrc_netapi,$(USEMODULE)))
DIRS += netapi
endif
Expand Down
Loading

0 comments on commit fc6896b

Please sign in to comment.