/** * Disconnect and clean up * * @param icb The connection control block */ static void cleanup_disconnect(connection_t *cxn) { uint8_t *data; biglist_t *ble; cxn->status.disconnect_count++; /* Close this socket. */ if (cxn->sd >= 0) { ind_soc_socket_unregister(cxn->sd); close(cxn->sd); } cxn->sd = -1; cxn->generation_id++; /* @fixme Is it possible there's a message that should be processed? */ LOG_VERBOSE(cxn, "Closing connection, current read buf has %d bytes", cxn->read_bytes); cxn->read_bytes = 0; /* Clear write queue */ BIGLIST_FOREACH_DATA(ble, cxn->output_list, uint8_t *, data) { LOG_TRACE(cxn, "Freeing outgoing msg %p", data); INDIGO_MEM_FREE(data); } biglist_free(cxn->output_list); cxn->output_list = NULL; cxn->bytes_enqueued = 0; cxn->pkts_enqueued = 0; cxn->output_head_offset = 0; }
ft_instance_t ft_hash_create(ft_config_t *config) { ft_instance_t ft; int bytes; int idx; if (config->max_entries <= 0) { LOG_ERROR("Hash flow table only supports fixed number of buckets"); return NULL; } /* Allocate the flow table itself */ ft = INDIGO_MEM_ALLOC(sizeof(*ft)); if (ft == NULL) { LOG_ERROR("ERROR: Flow table (hash) creation failed"); return NULL; } INDIGO_MEM_SET(ft, 0, sizeof(*ft)); INDIGO_MEM_COPY(&ft->config, config, sizeof(ft_config_t)); ft->magic = FT_HASH_MAGIC_NUMBER; list_init(&ft->free_list); list_init(&ft->all_list); /* Allocate and init the flow entries */ bytes = sizeof(ft_entry_t) * config->max_entries; ft->flow_entries = INDIGO_MEM_ALLOC(bytes); if (ft->flow_entries == NULL) { LOG_ERROR("ERROR: Flow table (hash) creation failed"); INDIGO_MEM_FREE(ft); return NULL; } INDIGO_MEM_SET(ft->flow_entries, 0, bytes); /* Put the flow entries on the free list */ for (idx = 0; idx < config->max_entries; idx++) { list_push(&ft->free_list, &ft->flow_entries[idx].table_links); } /* Allocate and init buckets for each search type */ bytes = sizeof(list_head_t) * config->prio_bucket_count; ft->prio_buckets = INDIGO_MEM_ALLOC(bytes); if (ft->prio_buckets == NULL) { LOG_ERROR("ERROR: Flow table, prio bucket alloc failed"); ft_hash_delete(ft); return NULL; } INDIGO_MEM_SET(ft->prio_buckets, 0, bytes); for (idx = 0; idx < config->prio_bucket_count; idx++) { list_init(&ft->prio_buckets[idx]); } bytes = sizeof(list_head_t) * config->match_bucket_count; ft->match_buckets = INDIGO_MEM_ALLOC(bytes); if (ft->match_buckets == NULL) { LOG_ERROR("ERROR: Flow table, match bucket alloc failed"); ft_hash_delete(ft); return NULL; } INDIGO_MEM_SET(ft->match_buckets, 0, bytes); for (idx = 0; idx < config->match_bucket_count; idx++) { list_init(&ft->match_buckets[idx]); } bytes = sizeof(list_head_t) * config->flow_id_bucket_count; ft->flow_id_buckets = INDIGO_MEM_ALLOC(bytes); if (ft->flow_id_buckets == NULL) { LOG_ERROR("ERROR: Flow table, flow id bucket alloc failed"); ft_hash_delete(ft); return NULL; } INDIGO_MEM_SET(ft->flow_id_buckets, 0, bytes); for (idx = 0; idx < config->flow_id_bucket_count; idx++) { list_init(&ft->flow_id_buckets[idx]); } return ft; }