Skip site navigation (1)Skip section navigation (2)
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>