Exemplo n.º 1
0
indigo_error_t
ft_hash_flow_add(ft_instance_t ft, indigo_flow_id_t id,
                 of_flow_add_t *flow_add, ft_entry_t **entry_p)
{
    ft_entry_t *entry;
    list_links_t *links;
    indigo_error_t rv;

    INDIGO_ASSERT(ft->magic == FT_HASH_MAGIC_NUMBER);

    LOG_TRACE("Adding flow " INDIGO_FLOW_ID_PRINTF_FORMAT, id);

    if (flow_add->version != OF_VERSION_1_0) { /* @fixme */
        LOG_ERROR("ERROR: bad version in ft_hash_flow_add");
        return INDIGO_ERROR_VERSION;
    }

    /* If flow ID already exists, error. */
    if (ft_id_lookup(ft, id) != NULL) {
        return INDIGO_ERROR_EXISTS;
    }

    /* Grab an entry from the free list */
    if ((links = list_pop(&ft->free_list)) == NULL) {
        ++(ft->status.table_full_errors);
        return INDIGO_ERROR_RESOURCE;
    }
    entry = FT_ENTRY_CONTAINER(links, table);

    if ((rv = ft_entry_setup(entry, id, flow_add)) < 0) {
        return rv;
    }

    ft_entry_link(ft, entry);
    ft->status.adds += 1;
    ft->status.current_count += 1;

    if (entry_p != NULL) {
        *entry_p = entry;
    }

    return INDIGO_ERROR_NONE;
}
Exemplo n.º 2
0
void
ind_core_expiration_add(ft_entry_t *entry)
{
    int reason;
    indigo_time_t expiration_time = calc_expiration_time(entry, &reason);
    list_links_t *cur;

    /* Iterate over list in reverse order */
    for (cur = expiration_queue.links.prev;
         cur != &expiration_queue.links;
         cur = cur->prev) {
        ft_entry_t *other = FT_ENTRY_CONTAINER(cur, expiration);
        if (calc_expiration_time(other, &reason) <= expiration_time) {
            /* 'other' expires before us. Insert after it. */
            list_insert_after(cur, &entry->expiration_links);
            return;
        }
    }

    /* Lowest expiration time. Insert at front of list. */
    list_unshift(&expiration_queue, &entry->expiration_links);
}
Exemplo n.º 3
0
static ind_soc_task_status_t
expiration_task(void *cookie)
{
    indigo_time_t current_time = INDIGO_CURRENT_TIME;
    (void) cookie;

    while (!list_empty(&expiration_queue)) {
        int reason;
        list_links_t *links = expiration_queue.links.next;
        ft_entry_t *entry = FT_ENTRY_CONTAINER(links, expiration);
        if (calc_expiration_time(entry, &reason) <= current_time) {
            expire_flow(entry, reason);
        } else {
            break;
        }
        if (ind_soc_should_yield()) {
            return IND_SOC_TASK_CONTINUE;
        }
    }

    task_running = false;
    return IND_SOC_TASK_FINISHED;
}