void mcast_algo_deinit(struct vr_rtable *rtable, struct rtable_fspec *fs, bool soft_reset) { if (!vn_rtable) return; vr_htable_trav(vn_rtable, 0, mcast_entry_free, NULL); if (!soft_reset) { vr_htable_delete(vn_rtable); rtable->algo_data = NULL; vn_rtable = NULL; } }
vr_htable_t __vr_htable_create(struct vrouter *router, unsigned int entries, void *htable, unsigned int oentries, void *otable, unsigned int entry_size, unsigned int key_size, unsigned int bucket_size, get_hentry_key get_entry_key) { int i; struct vr_htable *table; vr_hentry_t *ent, *prev; struct iovec iov; if (!entry_size || !entries || !get_entry_key) return NULL; if (!bucket_size) bucket_size = VR_HENTRIES_PER_BUCKET; /* Ceil to near upper number, which is dividable by bucket_size */ entries = ((entries + bucket_size -1) / bucket_size) * bucket_size; table = vr_zalloc(sizeof(struct vr_htable), VR_HTABLE_OBJECT); if (!table) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, sizeof(struct vr_htable)); goto exit; } if (!htable) { table->ht_htable = vr_btable_alloc(entries, entry_size); } else { iov.iov_base = htable; iov.iov_len = entry_size * entries; table->ht_htable = vr_btable_attach(&iov, 1, entry_size); } if (!table->ht_htable) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, entries); goto exit; } if (oentries) { if (!otable) { table->ht_otable = vr_btable_alloc(oentries, entry_size); } else { iov.iov_base = otable; iov.iov_len = entry_size * oentries; table->ht_otable = vr_btable_attach(&iov, 1, entry_size); } if (!table->ht_otable) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, oentries); goto exit; } /* * If there is an over flow table, create the delete data for * main flow table */ i = entries / bucket_size; table->ht_dtable = vr_btable_alloc(i, sizeof(struct vr_hentry_delete_data)); if (!table->ht_dtable) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, i); goto exit; } } for (i = 0; i < entries; i++) { ent = vr_btable_get(table->ht_htable, i); ent->hentry_index = i; ent->hentry_next_index = VR_INVALID_HENTRY_INDEX; } prev = NULL; for (i = 0; i < oentries; i++) { ent = vr_btable_get(table->ht_otable, i); ent->hentry_index = entries + i; ent->hentry_next_index = VR_INVALID_HENTRY_INDEX; if (i == 0) table->ht_free_oentry_head = ent; else prev->hentry_next = ent; ent->hentry_flags |= VR_HENTRY_FLAG_IN_FREE_LIST; prev = ent; } table->ht_hentries = entries; table->ht_oentries = oentries; table->ht_entry_size = entry_size; table->ht_key_size = key_size; table->ht_get_key = get_entry_key; table->ht_bucket_size = bucket_size; table->ht_router = router; table->ht_used_oentries = 0; return (vr_htable_t)table; exit: vr_htable_delete((vr_htable_t)table); return NULL; }