Date: Sat, 30 Aug 2014 17:18:11 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r270846 - projects/ipfw/sys/netpfil/ipfw Message-ID: <201408301718.s7UHIBgT044308@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Sat Aug 30 17:18:11 2014 New Revision: 270846 URL: http://svnweb.freebsd.org/changeset/base/270846 Log: * Make objhash api a bit more abstract by providing ability to specify own hash/compare functions. * Add requirement for table algorithms to copy "valie" field in @add callback instead of "prepare_add". * Document existing requirement for table algorithms to store value of deleted record to @tei. Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h ============================================================================== --- projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h Sat Aug 30 17:14:47 2014 (r270845) +++ projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h Sat Aug 30 17:18:11 2014 (r270846) @@ -267,7 +267,7 @@ struct ip_fw_chain { uint32_t id; /* ruleset id */ int n_rules; /* number of static rules */ LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */ - void *tablestate; /* runtime table info */ + void *tablestate; /* runtime table info */ int *idxmap; /* skipto array of rules */ #if defined( __linux__ ) || defined( _WIN32 ) spinlock_t rwmtx; @@ -519,6 +519,9 @@ caddr_t ipfw_get_sopt_header(struct sock typedef void (objhash_cb_t)(struct namedobj_instance *ni, struct named_object *, void *arg); +typedef uint32_t (objhash_hash_f)(struct namedobj_instance *ni, void *key, + uint32_t kopt); +typedef int (objhash_cmp_f)(struct named_object *no, void *key, uint32_t kopt); struct namedobj_instance *ipfw_objhash_create(uint32_t items); void ipfw_objhash_destroy(struct namedobj_instance *); void ipfw_objhash_bitmap_alloc(uint32_t items, void **idx, int *pblocks); @@ -527,6 +530,7 @@ void ipfw_objhash_bitmap_merge(struct na void ipfw_objhash_bitmap_swap(struct namedobj_instance *ni, void **idx, int *blocks); void ipfw_objhash_bitmap_free(void *idx, int blocks); +void ipfw_objhash_set_hashf(struct namedobj_instance *ni, objhash_hash_f *f); struct named_object *ipfw_objhash_lookup_name(struct namedobj_instance *ni, uint32_t set, char *name); struct named_object *ipfw_objhash_lookup_kidx(struct namedobj_instance *ni, @@ -540,6 +544,8 @@ void ipfw_objhash_foreach(struct namedob void *arg); int ipfw_objhash_free_idx(struct namedobj_instance *ni, uint16_t idx); int ipfw_objhash_alloc_idx(void *n, uint16_t *pidx); +void ipfw_objhash_set_funcs(struct namedobj_instance *ni, + objhash_hash_f *hash_f, objhash_cmp_f *cmp_f); /* In ip_fw_table.c */ struct table_info; Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c ============================================================================== --- projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c Sat Aug 30 17:14:47 2014 (r270845) +++ projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c Sat Aug 30 17:18:11 2014 (r270846) @@ -88,12 +88,15 @@ struct namedobj_instance { uint32_t max_blocks; /* number of "long" blocks in bitmask */ uint32_t count; /* number of items */ uint16_t free_off[IPFW_MAX_SETS]; /* first possible free offset */ + objhash_hash_f *hash_f; + objhash_cmp_f *cmp_f; }; #define BLOCK_ITEMS (8 * sizeof(u_long)) /* Number of items for ffsl() */ -static uint32_t objhash_hash_name(struct namedobj_instance *ni, uint32_t set, - char *name); -static uint32_t objhash_hash_val(struct namedobj_instance *ni, uint32_t val); +static uint32_t objhash_hash_name(struct namedobj_instance *ni, void *key, + uint32_t kopt); +static uint32_t objhash_hash_idx(struct namedobj_instance *ni, uint32_t val); +static int objhash_cmp_name(struct named_object *no, void *name, uint32_t set); static int ipfw_flush_sopt_data(struct sockopt_data *sd); @@ -3078,6 +3081,10 @@ ipfw_objhash_create(uint32_t items) for (i = 0; i < ni->nv_size; i++) TAILQ_INIT(&ni->values[i]); + /* Set default hashing/comparison functions */ + ni->hash_f = objhash_hash_name; + ni->cmp_f = objhash_cmp_name; + /* Allocate bitmask separately due to possible resize */ ipfw_objhash_bitmap_alloc(items, (void*)&ni->idx_mask, &ni->max_blocks); @@ -3092,18 +3099,37 @@ ipfw_objhash_destroy(struct namedobj_ins free(ni, M_IPFW); } +void +ipfw_objhash_set_funcs(struct namedobj_instance *ni, objhash_hash_f *hash_f, + objhash_cmp_f *cmp_f) +{ + + ni->hash_f = hash_f; + ni->cmp_f = cmp_f; +} + static uint32_t -objhash_hash_name(struct namedobj_instance *ni, uint32_t set, char *name) +objhash_hash_name(struct namedobj_instance *ni, void *name, uint32_t set) { uint32_t v; - v = fnv_32_str(name, FNV1_32_INIT); + v = fnv_32_str((char *)name, FNV1_32_INIT); return (v % ni->nn_size); } +static int +objhash_cmp_name(struct named_object *no, void *name, uint32_t set) +{ + + if ((strcmp(no->name, (char *)name) == 0) && (no->set == set)) + return (0); + + return (1); +} + static uint32_t -objhash_hash_val(struct namedobj_instance *ni, uint32_t val) +objhash_hash_idx(struct namedobj_instance *ni, uint32_t val) { uint32_t v; @@ -3118,10 +3144,10 @@ ipfw_objhash_lookup_name(struct namedobj struct named_object *no; uint32_t hash; - hash = objhash_hash_name(ni, set, name); + hash = ni->hash_f(ni, name, set); TAILQ_FOREACH(no, &ni->names[hash], nn_next) { - if ((strcmp(no->name, name) == 0) && (no->set == set)) + if (ni->cmp_f(no, name, set) == 0) return (no); } @@ -3134,7 +3160,7 @@ ipfw_objhash_lookup_kidx(struct namedobj struct named_object *no; uint32_t hash; - hash = objhash_hash_val(ni, kidx); + hash = objhash_hash_idx(ni, kidx); TAILQ_FOREACH(no, &ni->values[hash], nv_next) { if (no->kidx == kidx) @@ -3160,10 +3186,10 @@ ipfw_objhash_add(struct namedobj_instanc { uint32_t hash; - hash = objhash_hash_name(ni, no->set, no->name); + hash = ni->hash_f(ni, no->name, no->set); TAILQ_INSERT_HEAD(&ni->names[hash], no, nn_next); - hash = objhash_hash_val(ni, no->kidx); + hash = objhash_hash_idx(ni, no->kidx); TAILQ_INSERT_HEAD(&ni->values[hash], no, nv_next); ni->count++; @@ -3174,10 +3200,10 @@ ipfw_objhash_del(struct namedobj_instanc { uint32_t hash; - hash = objhash_hash_name(ni, no->set, no->name); + hash = ni->hash_f(ni, no->name, no->set); TAILQ_REMOVE(&ni->names[hash], no, nn_next); - hash = objhash_hash_val(ni, no->kidx); + hash = objhash_hash_idx(ni, no->kidx); TAILQ_REMOVE(&ni->values[hash], no, nv_next); ni->count--; @@ -3238,7 +3264,7 @@ ipfw_objhash_free_idx(struct namedobj_in } /* - * Allocate new index in given set and stores in in @pidx. + * Allocate new index in given instance and stores in in @pidx. * Returns 0 on success. */ int Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c ============================================================================== --- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c Sat Aug 30 17:14:47 2014 (r270845) +++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c Sat Aug 30 17:18:11 2014 (r270846) @@ -106,6 +106,9 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne * void *ta_buf); * MANDATORY, unlocked. (M_WAITOK). Returns 0 on success. * + * Allocates state and fills it in with all necessary data (EXCEPT value) + * from @tei to minimize operations needed to be done under WLOCK. + * "value" field has to be copied to new entry in @add callback. * Buffer ta_buf of size ta->ta_buf_sz may be used to store * allocated state. * @@ -132,6 +135,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne * TEI_FLAGS_UPDATE: request to add or update entry. * TEI_FLAGS_DONTADD: request to update (but not add) entry. * * Caller is required to do the following: + * copy real entry value from @tei * entry added: return 0, set 1 to @pnum * entry updated: return 0, store 0 to @pnum, store old value in @tei, * add TEI_FLAGS_UPDATED flag to @tei. @@ -148,7 +152,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne * * Delete entry using previously set up in @ta_buf. * * Caller is required to do the following: - * entry deleted: return 0, set 1 to @pnum + * entry deleted: return 0, set 1 to @pnum, store old value in @tei. * entry not found: return ENOENT * other error: return non-zero error code. * @@ -620,7 +624,6 @@ ta_prepare_add_radix(struct ip_fw_chain if (mlen > 32) return (EINVAL); ent = malloc(sizeof(*ent), M_IPFW_TBL, M_WAITOK | M_ZERO); - ent->value = tei->value; ent->masklen = mlen; addr = (struct sockaddr *)&ent->addr; @@ -633,7 +636,6 @@ ta_prepare_add_radix(struct ip_fw_chain if (mlen > 128) return (EINVAL); xent = malloc(sizeof(*xent), M_IPFW_TBL, M_WAITOK | M_ZERO); - xent->value = tei->value; xent->masklen = mlen; addr = (struct sockaddr *)&xent->addr6; @@ -667,10 +669,14 @@ ta_add_radix(void *ta_state, struct tabl cfg = (struct radix_cfg *)ta_state; tb = (struct ta_buf_radix *)ta_buf; - if (tei->subtype == AF_INET) + /* Save current entry value from @tei */ + if (tei->subtype == AF_INET) { rnh = ti->state; - else + ((struct radix_addr_entry *)tb->ent_ptr)->value = tei->value; + } else { rnh = ti->xstate; + ((struct radix_addr_xentry *)tb->ent_ptr)->value = tei->value; + } /* Search for an entry first */ rn = rnh->rnh_lookup(tb->addr_ptr, tb->mask_ptr, rnh); @@ -1320,7 +1326,6 @@ tei_to_chash_ent(struct tentry_info *tei /* Unknown CIDR type */ return (EINVAL); } - ent->value = tei->value; return (0); } @@ -1439,6 +1444,10 @@ ta_add_chash(void *ta_state, struct tabl hash = 0; exists = 0; + /* Read current value from @tei */ + ent->value = tei->value; + + /* Read cuurrent value */ if (tei->subtype == AF_INET) { if (tei->masklen != cfg->mask4) return (EINVAL); @@ -2030,7 +2039,6 @@ ta_prepare_add_ifidx(struct ip_fw_chain return (EINVAL); ife = malloc(sizeof(struct ifentry), M_IPFW_TBL, M_WAITOK | M_ZERO); - ife->value = tei->value; ife->ic.cb = if_notifier; ife->ic.cbdata = ife; @@ -2063,6 +2071,7 @@ ta_add_ifidx(void *ta_state, struct tabl ife = tb->ife; ife->icfg = icfg; + ife->value = tei->value; tmp = (struct ifentry *)ipfw_objhash_lookup_name(icfg->ii, 0, ifname); @@ -2577,7 +2586,6 @@ ta_prepare_add_numarray(struct ip_fw_cha tb = (struct ta_buf_numarray *)ta_buf; tb->na.number = *((uint32_t *)tei->paddr); - tb->na.value = tei->value; return (0); } @@ -2595,6 +2603,9 @@ ta_add_numarray(void *ta_state, struct t tb = (struct ta_buf_numarray *)ta_buf; cfg = (struct numarray_cfg *)ta_state; + /* Read current value from @tei */ + tb->na.value = tei->value; + ri = numarray_find(ti, &tb->na.number); if (ri != NULL) { @@ -3155,7 +3166,6 @@ tei_to_fhash_ent(struct tentry_info *tei ent->af = tei->subtype; ent->proto = tfe->proto; - ent->value = tei->value; ent->dport = ntohs(tfe->dport); ent->sport = ntohs(tfe->sport); @@ -3287,6 +3297,9 @@ ta_add_fhash(void *ta_state, struct tabl ent = (struct fhashentry *)tb->ent_ptr; exists = 0; + /* Read current value from @tei */ + ent->value = tei->value; + head = cfg->head; hash = hash_flow_ent(ent, cfg->size);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408301718.s7UHIBgT044308>