Example #1
0
static struct vr_flow_entry *
vr_find_free_entry(struct vrouter *router, struct vr_flow_key *key,
        unsigned int *fe_index)
{
    unsigned int i, index, hash;
    struct vr_flow_entry *tmp_fe, *fe = NULL;

    *fe_index = 0;

    hash = vr_hash(key, sizeof(*key), 0);

    index = (hash % vr_flow_entries) & ~(VR_FLOW_ENTRIES_PER_BUCKET - 1);
    for (i = 0; i < VR_FLOW_ENTRIES_PER_BUCKET; i++) {
        tmp_fe = vr_flow_table_entry_get(router, index);
        if (tmp_fe && !(tmp_fe->fe_flags & VR_FLOW_FLAG_ACTIVE)) {
            if (vr_set_flow_active(tmp_fe)) {
                vr_init_flow_entry(tmp_fe);
                fe = tmp_fe;
                break;
            }
        }
        index++;
    }
        
    if (!fe) {
        index = hash % vr_oflow_entries;
        for (i = 0; i < vr_oflow_entries; i++) {
            tmp_fe = vr_oflow_table_entry_get(router, index);
            if (tmp_fe && !(tmp_fe->fe_flags & VR_FLOW_FLAG_ACTIVE)) {
                if (vr_set_flow_active(tmp_fe)) {
                    vr_init_flow_entry(tmp_fe);
                    fe = tmp_fe;
                    break;
                }
            }
            index = (index + 1) % vr_oflow_entries;
        }

        if (fe)
            *fe_index += vr_flow_entries;
    }

    if (fe) {
        *fe_index += index;
        memcpy(&fe->fe_key, key, sizeof(*key));
    }

    return fe;
}
Example #2
0
static struct vr_flow_entry *
vr_find_free_entry(struct vrouter *router, struct vr_flow *key, uint8_t type,
        bool need_hold, unsigned int *fe_index)
{
    unsigned int i, index, hash;
    struct vr_flow_entry *tmp_fe, *fe = NULL;

    *fe_index = 0;

    hash = vr_hash(key, key->flow_key_len, 0);

    index = (hash % vr_flow_entries) & ~(VR_FLOW_ENTRIES_PER_BUCKET - 1);
    for (i = 0; i < VR_FLOW_ENTRIES_PER_BUCKET; i++) {
        tmp_fe = vr_flow_table_entry_get(router, index);
        if (tmp_fe && !(tmp_fe->fe_flags & VR_FLOW_FLAG_ACTIVE)) {
            if (vr_set_flow_active(tmp_fe)) {
                vr_init_flow_entry(tmp_fe);
                fe = tmp_fe;
                break;
            }
        }
        index++;
    }

    if (!fe) {
        index = hash % vr_oflow_entries;
        for (i = 0; i < vr_oflow_entries; i++) {
            tmp_fe = vr_oflow_table_entry_get(router, index);
            if (tmp_fe && !(tmp_fe->fe_flags & VR_FLOW_FLAG_ACTIVE)) {
                if (vr_set_flow_active(tmp_fe)) {
                    vr_init_flow_entry(tmp_fe);
                    fe = tmp_fe;
                    break;
                }
            }
            index = (index + 1) % vr_oflow_entries;
        }

        if (fe)
            *fe_index += vr_flow_entries;
    }

    if (fe) {
        *fe_index += index;
        if (need_hold) {
            fe->fe_hold_list = vr_zalloc(sizeof(struct vr_flow_queue));
            if (!fe->fe_hold_list) {
                vr_reset_flow_entry(router, fe, *fe_index);
                fe = NULL;
            } else {
                fe->fe_hold_list->vfq_index = *fe_index;
            }
        }

        if (fe) {
            fe->fe_type = type;
            fe->fe_key.flow_key_len = key->flow_key_len;
            memcpy(&fe->fe_key, key, key->flow_key_len);
        }
    }

    return fe;
}