/** * @brief selects potential source address candidates * @see <a href="http://tools.ietf.org/html/rfc6724#section-4"> * RFC6724, section 4 * </a> * @param[in] netif the interface used for sending * @param[in] dst the destination address * @param[in] ll_only only consider link-local addresses * @param[out] candidate_set a bitfield representing all addresses * configured to @p netif, potential candidates * will be marked as 1 * * @return -1 if no candidates were found * @return the index of the first candidate otherwise * * @pre the interface entry and its set of addresses must not be changed during * runtime of this function */ static int _create_candidate_set(const gnrc_netif_t *netif, const ipv6_addr_t *dst, bool ll_only, uint8_t *candidate_set) { int res = -1; DEBUG("gathering candidates\n"); /* currently this implementation supports only addresses as source address * candidates assigned to this interface. Thus we assume all addresses to be * on interface @p netif */ (void) dst; for (int i = 0; i < GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) { const ipv6_addr_t *tmp = &(netif->ipv6.addrs[i]); DEBUG("Checking address: %s\n", ipv6_addr_to_str(addr_str, tmp, sizeof(addr_str))); /* "In any case, multicast addresses and the unspecified address MUST NOT * be included in a candidate set." */ if ((netif->ipv6.addrs_flags[i] == 0) || (gnrc_netif_ipv6_addr_get_state(netif, i) == GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE)) { continue; } /* Check if we only want link local addresses */ if (ll_only && !ipv6_addr_is_link_local(tmp)) { continue; } /* "For all multicast and link-local destination addresses, the set of * candidate source addresses MUST only include addresses assigned to * interfaces belonging to the same link as the outgoing interface." * * "For site-local unicast destination addresses, the set of candidate * source addresses MUST only include addresses assigned to interfaces * belonging to the same site as the outgoing interface." * -> we should also be fine, since we're only iterating addresses of * the sending interface */ /* put all other addresses into the candidate set */ DEBUG("add to candidate set\n"); bf_set(candidate_set, i); if (res < 0) { res = i; } } return res; }
static inline bool _is_valid(const gnrc_netif_t *netif, int idx) { return (gnrc_netif_ipv6_addr_get_state(netif, idx) == GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID); }
static inline bool _is_tentative(const gnrc_netif_t *netif, int idx) { return (gnrc_netif_ipv6_addr_get_state(netif, idx) & GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE); }