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