Exemplo n.º 1
0
void indigo_core_table_register(uint8_t table_id, const char *name,
                                const indigo_core_table_ops_t *ops, void *priv)
{
    AIM_TRUE_OR_DIE(strlen(name) <= OF_MAX_TABLE_NAME_LEN);

    list_links_t *cur, *next;
    ft_entry_t *entry;
    FT_ITER(ind_core_ft, entry, cur, next) {
        if (entry->table_id == table_id) {
            ind_core_flow_entry_delete(entry, OF_FLOW_REMOVED_REASON_DELETE,
                                       INDIGO_CXN_ID_UNSPECIFIED);
        }
    }

    ind_core_table_t *table = aim_zmalloc(sizeof(*table));
    strncpy(table->name, name, sizeof(table->name));
    table->ops = ops;
    table->priv = priv;
    table->num_flows = 0;

    AIM_TRUE_OR_DIE(ind_core_tables[table_id] == NULL);
    ind_core_tables[table_id] = table;
    ind_core_num_tables_registered++;

    AIM_LOG_VERBOSE("Registered flowtable \"%s\" with table id %d", name, table_id);
}
Exemplo n.º 2
0
static void
expire_flow(ft_entry_t *entry, int reason)
{
    if (reason == INDIGO_FLOW_REMOVED_HARD_TIMEOUT) {
        LOG_TRACE("Hard TO (%d): " INDIGO_FLOW_ID_PRINTF_FORMAT,
                  entry->hard_timeout,
                  INDIGO_FLOW_ID_PRINTF_ARG(entry->id));
        ind_core_flow_entry_delete(entry, reason, INDIGO_CXN_ID_UNSPECIFIED);
    } else if (reason == OF_FLOW_REMOVED_REASON_IDLE_TIMEOUT) {
        int rv;
        bool hit;

        /* Get hit status for idle timeouts */
        ind_core_table_t *table = ind_core_table_get(entry->table_id);
        if (table != NULL) {
            rv = table->ops->entry_hit_status_get(table->priv, INDIGO_CXN_ID_UNSPECIFIED,
                                                  entry->priv, &hit);
        } else {
            rv = indigo_fwd_flow_hit_status_get(entry->id, &hit);
        }

        if (rv != INDIGO_ERROR_NONE) {
            LOG_ERROR("Failed to get hit status for flow "
                      INDIGO_FLOW_ID_PRINTF_FORMAT": %s",
                      entry->id, indigo_strerror(rv));
            return;
        }

        if (hit || entry->flags & OF_FLOW_MOD_FLAG_BSN_SEND_IDLE) {
            /* Reinsert entry into the expiration list */
            entry->last_counter_change = INDIGO_CURRENT_TIME;
            ind_core_expiration_remove(entry);
            ind_core_expiration_add(entry);
        }

        if (!hit) {
            if (entry->flags & OF_FLOW_MOD_FLAG_BSN_SEND_IDLE) {
                send_idle_notification(entry);
            } else {
                LOG_TRACE("Idle TO (%d): " INDIGO_FLOW_ID_PRINTF_FORMAT,
                          entry->idle_timeout,
                          INDIGO_FLOW_ID_PRINTF_ARG(entry->id));
                ind_core_flow_entry_delete(entry, reason, INDIGO_CXN_ID_UNSPECIFIED);
            }
        }
    }
}
Exemplo n.º 3
0
void indigo_core_table_unregister(uint8_t table_id)
{
    ind_core_table_t *table = ind_core_tables[table_id];
    AIM_TRUE_OR_DIE(table != NULL);

    list_links_t *cur, *next;
    ft_entry_t *entry;
    FT_ITER(ind_core_ft, entry, cur, next) {
        if (entry->table_id == table_id) {
            ind_core_flow_entry_delete(entry, OF_FLOW_REMOVED_REASON_DELETE,
                                       INDIGO_CXN_ID_UNSPECIFIED);
        }
    }

    aim_free(table);
    ind_core_tables[table_id] = NULL;
    ind_core_num_tables_registered--;
}
Exemplo n.º 4
0
/**
 * Timer operation to expire flows.
 *
 * Calls indigo_fwd_flow_stats_get for each flow in the table. The expiration
 * is done in flow_expiration_timer_cb when the reply is received.
 *
 * Ignore this call if the module is not enabled.
 */
static void
flow_expiration_timer(void *cookie)
{
    ft_entry_t *entry;
    list_links_t *cur, *next;
    indigo_time_t current_time = INDIGO_CURRENT_TIME;

    if (!ind_core_module_enabled) {
        return;
    }

    FT_ITER(ind_core_ft, entry, cur, next) {
        indigo_error_t rv;
        indigo_fi_flow_stats_t flow_stats;

        if (entry->hard_timeout > 0) {
            uint32_t delta;
            delta = INDIGO_TIME_DIFF_ms(entry->insert_time,
                                        current_time) / 1000;
            if (delta >= entry->hard_timeout) {
                LOG_TRACE("Hard TO (%d): " INDIGO_FLOW_ID_PRINTF_FORMAT,
                          entry->hard_timeout,
                          INDIGO_FLOW_ID_PRINTF_ARG(entry->id));
                ind_core_flow_entry_delete(entry, INDIGO_FLOW_REMOVED_HARD_TIMEOUT,
                                           INDIGO_CXN_ID_UNSPECIFIED);
                continue;
            }
        }

        /* Update local copy of counters */
        /* Only used currently for idle timeouts */
        if (entry->idle_timeout > 0) {
            rv = indigo_fwd_flow_stats_get(entry->id, &flow_stats);
            if (rv != INDIGO_ERROR_NONE) {
                LOG_ERROR("Failed to get stats for flow "INDIGO_FLOW_ID_PRINTF_FORMAT": %d",
                          entry->id, rv);
                continue;
            }

            if (entry->packets != flow_stats.packets) {
                entry->packets = flow_stats.packets;
                entry->last_counter_change = current_time;
            }
            if (entry->bytes != flow_stats.bytes) {
                entry->bytes = flow_stats.bytes;
                entry->last_counter_change = current_time;
            }
        }

        if (entry->idle_timeout > 0) {
            uint32_t delta;
            delta = INDIGO_TIME_DIFF_ms(entry->last_counter_change,
                                        current_time) / 1000;
            if (delta >= entry->idle_timeout) {
                LOG_TRACE("Idle TO (%d): " INDIGO_FLOW_ID_PRINTF_FORMAT,
                          entry->idle_timeout, INDIGO_FLOW_ID_PRINTF_ARG(entry->id));
                ind_core_flow_entry_delete(entry, INDIGO_FLOW_REMOVED_IDLE_TIMEOUT,
                                           INDIGO_CXN_ID_UNSPECIFIED);
                continue;
            }
        }
    }