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; }
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); }
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; }