示例#1
0
文件: fib.c 项目: robby14/RIOT
/**
 * @brief signals (sends a message to) all registered routing protocols
 *        registered with a matching prefix (usually this should be only one).
 *        The message informs the recipient that no next-hop is available for the
 *        requested destination address.
 *        The receiver MUST copy the content, i.e. the address before reply.
 *
 * @param[in] dst       the destination address
 * @param[in] dst_size  the destination address size
 *
 * @return 0 on a new available entry,
 *         -ENOENT if no suiting entry is provided.
 */
static int fib_signal_rp(uint8_t *dst, size_t dst_size, uint32_t dst_flags)
{
    msg_t msg, reply;
    rp_address_msg_t content;
    content.address = dst;
    content.address_size = dst_size;
    content.address_flags = dst_flags;
    int ret = -ENOENT;

    msg.type = FIB_MSG_RP_SIGNAL;
    msg.content.ptr = (void *)&content;

    for (size_t i = 0; i < FIB_MAX_REGISTERED_RP; ++i) {
        if (notify_rp[i] != KERNEL_PID_UNDEF) {
            DEBUG("[fib_signal_rp] send msg@: %p to pid[%d]: %d\n", \
                  msg.content.ptr, (int)i, (int)notify_rp[i]);

            /* do only signal a RP if its registered prefix matches */
            size_t dst_size_in_bits = dst_size<<3;
            if (universal_address_compare(prefix_rp[i], dst, &dst_size_in_bits) == 1) {
                /* the receiver, i.e. the RP, MUST copy the content value.
                 * using the provided pointer after replying this message
                 * will lead to errors
                 */
                msg_send_receive(&msg, &reply, notify_rp[i]);
                DEBUG("[fib_signal_rp] got reply.\n");
            }
        }
    }

    return ret;
}
示例#2
0
文件: fib.c 项目: JiapengLi/RIOT
/**
 * @brief returns pointer to the entry for the given destination address
 *
 * @param[in] dst                  the destination address
 * @param[in] dst_size             the destination address size
 * @param[out] entry_arr           the array to scribe the found match
 * @param[in, out] entry_arr_size  the number of entries provided by entry_arr (should be always 1)
 *                                 this value is overwritten with the actual found number
 *
 * @return 0 if we found a next-hop prefix
 *         1 if we found the exact address next-hop
 *         -EHOSTUNREACH if no fitting next-hop is available
 */
static int fib_find_entry(uint8_t *dst, size_t dst_size,
                          fib_entry_t **entry_arr, size_t *entry_arr_size)
{
    timex_t now;
    vtimer_now(&now);

    size_t count = 0;
    size_t prefix_size = 0;
    size_t match_size = dst_size;
    int ret = -EHOSTUNREACH;

    for (size_t i = 0; i < FIB_MAX_FIB_TABLE_ENTRIES; ++i) {

        /* autoinvalidate if the entry lifetime is not set to not expire */
        if ((fib_table[i].lifetime.seconds != FIB_LIFETIME_NO_EXPIRE)
            || (fib_table[i].lifetime.microseconds != FIB_LIFETIME_NO_EXPIRE)) {

            /* check if the lifetime expired */
            if (timex_cmp(now, fib_table[i].lifetime) > -1) {
                /* remove this entry if its lifetime expired */
                fib_table[i].lifetime.seconds = 0;
                fib_table[i].lifetime.microseconds = 0;

                if (fib_table[i].global != NULL) {
                    universal_address_rem(fib_table[i].global);
                    fib_table[i].global = NULL;
                }

                if (fib_table[i].next_hop != NULL) {
                    universal_address_rem(fib_table[i].next_hop);
                    fib_table[i].next_hop = NULL;
                }
            }
        }

        if ((prefix_size < dst_size) &&
            (fib_table[i].global != NULL) &&
            (universal_address_compare(fib_table[i].global, dst, &match_size) == 0)) {

            /* If we found an exact match */
            if (match_size == dst_size) {
                entry_arr[0] = &(fib_table[i]);
                *entry_arr_size = 1;
                /* we will not find a better one so we return */
                return 1;
            }
            else {
                /* we try to find the most fitting prefix */
                if (match_size > prefix_size) {
                    entry_arr[0] = &(fib_table[i]);
                    /* we could find a better one so we move on */
                    ret = 0;
                }
            }

            prefix_size = match_size;
            match_size = dst_size;
            count = 1;
        }
    }

    *entry_arr_size = count;
    return ret;
}
示例#3
0
文件: fib.c 项目: daniel-k/RIOT
/**
 * @brief returns pointer to the entry for the given destination address
 *
 * @param[in] table                the FIB table to search in
 * @param[in] dst                  the destination address
 * @param[in] dst_size             the destination address size
 * @param[out] entry_arr           the array to scribe the found match
 * @param[in, out] entry_arr_size  the number of entries provided by entry_arr (should be always 1)
 *                                 this value is overwritten with the actual found number
 *
 * @return 0 if we found a next-hop prefix
 *         1 if we found the exact address next-hop
 *         -EHOSTUNREACH if no fitting next-hop is available
 */
static int fib_find_entry(fib_table_t *table, uint8_t *dst, size_t dst_size,
                          fib_entry_t **entry_arr, size_t *entry_arr_size) {
    uint64_t now = xtimer_now64();

    size_t count = 0;
    size_t prefix_size = 0;
    size_t match_size = dst_size<<3;
    int ret = -EHOSTUNREACH;
    bool is_all_zeros_addr = true;

    for(size_t i = 0; i < dst_size; ++i) {
        if (dst[i] != 0) {
            is_all_zeros_addr = false;
            break;
        }
    }

    for (size_t i = 0; i < table->size; ++i) {

        /* autoinvalidate if the entry lifetime is not set to not expire */
        if (table->entries[i].lifetime != FIB_LIFETIME_NO_EXPIRE) {

            /* check if the lifetime expired */
            if (table->entries[i].lifetime < now) {
                /* remove this entry if its lifetime expired */
                table->entries[i].lifetime = 0;
                table->entries[i].global_flags = 0;
                table->entries[i].next_hop_flags = 0;
                table->entries[i].iface_id = KERNEL_PID_UNDEF;

                if (table->entries[i].global != NULL) {
                    universal_address_rem(table->entries[i].global);
                    table->entries[i].global = NULL;
                }

                if (table->entries[i].next_hop != NULL) {
                    universal_address_rem(table->entries[i].next_hop);
                    table->entries[i].next_hop = NULL;
                }
            }
        }

        if ((prefix_size < (dst_size<<3)) && (table->entries[i].global != NULL)) {

            int ret_comp = universal_address_compare(table->entries[i].global, dst, &match_size);
            /* If we found an exact match */
            if (ret_comp == 0 || (is_all_zeros_addr && match_size == 0)) {
                entry_arr[0] = &(table->entries[i]);
                *entry_arr_size = 1;
                /* we will not find a better one so we return */
                return 1;
            }
            else {
                /* we try to find the most fitting prefix */
                if (ret_comp == 1) {
                    entry_arr[0] = &(table->entries[i]);
                    /* we could find a better one so we move on */
                    ret = 0;

                    prefix_size = match_size;
                    match_size = dst_size<<3;
                    count = 1;
                }
            }
        }
    }

    *entry_arr_size = count;
    return ret;
}