Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Aug 2014 14:09:16 +0000 (UTC)
From:      Alexander V. Chernikov <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r269876 - projects/ipfw/sys/netpfil/ipfw
Message-ID:  <53ea200c.64ff.24e31b86@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Tue Aug 12 14:09:15 2014
New Revision: 269876
URL: http://svnweb.freebsd.org/changeset/base/269876

Log:
  * Rename has_space to need_modify to be consistent with 0 as return values.
  * document all callbacks supported by algorithms code.

Modified:
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Tue Aug 12 13:28:46 2014	(r269875)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Tue Aug 12 14:09:15 2014	(r269876)
@@ -623,7 +623,7 @@ cleanup:
  * need for reallocation.
  *
  * Callbacks order:
- * 0) has_space() (UH_WLOCK) - checks if @count items can be added w/o resize.
+ * 0) need_modify() (UH_WLOCK) - checks if @count items can be added w/o resize.
  *
  * 1) alloc_modify (no locks, M_WAITOK) - alloc new state based on @pflags.
  * 2) prepare_modifyt (UH_WLOCK) - copy old data into new storage
@@ -655,15 +655,15 @@ check_table_space(struct ip_fw_chain *ch
 	 */
 	while (true) {
 		pflags = 0;
-		if (ta->has_space(tc->astate, ti, count, &pflags) != 0) {
+		if (ta->need_modify(tc->astate, ti, count, &pflags) == 0) {
 			error = 0;
 			break;
 		}
 
 		/* We have to shrink/grow table */
 		IPFW_UH_WUNLOCK(ch);
+
 		memset(&ta_buf, 0, sizeof(ta_buf));
-		
 		if ((error = ta->prepare_mod(ta_buf, &pflags)) != 0) {
 			IPFW_UH_WLOCK(ch);
 			break;
@@ -673,7 +673,8 @@ check_table_space(struct ip_fw_chain *ch
 
 		/* Check if we still need to alter table */
 		ti = KIDX_TO_TI(ch, tc->no.kidx);
-		if (ta->has_space(tc->astate, ti, count, &pflags) != 0) {
+		if (ta->need_modify(tc->astate, ti, count, &pflags) == 0) {
+			IPFW_UH_WUNLOCK(ch);
 
 			/*
 			 * Other thread has already performed resize.
@@ -3230,4 +3231,3 @@ free:
 	return (error);
 }
 
-

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h	Tue Aug 12 13:28:46 2014	(r269875)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h	Tue Aug 12 14:09:15 2014	(r269876)
@@ -83,12 +83,12 @@ typedef int (ta_del)(void *ta_state, str
 typedef void (ta_flush_entry)(struct ip_fw_chain *ch, struct tentry_info *tei,
     void *ta_buf);
 
-typedef int (ta_has_space)(void *ta_state, struct table_info *ti,
+typedef int (ta_need_modify)(void *ta_state, struct table_info *ti,
     uint32_t count, uint64_t *pflags);
 typedef int (ta_prepare_mod)(void *ta_buf, uint64_t *pflags);
 typedef int (ta_fill_mod)(void *ta_state, struct table_info *ti,
     void *ta_buf, uint64_t *pflags);
-typedef int (ta_modify)(void *ta_state, struct table_info *ti,
+typedef void (ta_modify)(void *ta_state, struct table_info *ti,
     void *ta_buf, uint64_t pflags);
 typedef void (ta_flush_mod)(void *ta_buf);
 
@@ -121,7 +121,7 @@ struct table_algo {
 	ta_del		*del;
 	ta_flush_entry	*flush_entry;
 	ta_find_tentry	*find_tentry;
-	ta_has_space	*has_space;
+	ta_need_modify	*need_modify;
 	ta_prepare_mod	*prepare_mod;
 	ta_fill_mod	*fill_mod;
 	ta_modify	*modify;

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Tue Aug 12 13:28:46 2014	(r269875)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Tue Aug 12 14:09:15 2014	(r269876)
@@ -56,6 +56,221 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne
 #include <netpfil/ipfw/ip_fw_private.h>
 #include <netpfil/ipfw/ip_fw_table.h>
 
+
+/*
+ * IPFW table lookup algorithms.
+ *
+ * What is needed to add another table algo?
+ *
+ * Algo init:
+ * * struct table_algo has to be filled with:
+ *   name: "type:algoname" format, e.g. "cidr:radix". Currently
+ *     there are the following types: "cidr", "iface", "number" and "flow".
+ *   type: one of IPFW_TABLE_* types
+ *   flags: one or more TA_FLAGS_*
+ *   ta_buf_size: size of structure used to store add/del item state.
+ *     Needs to be less than TA_BUF_SZ.
+ *   callbacks: see below for description.
+ * * ipfw_add_table_algo / ipfw_del_table_algo has to be called
+ *
+ * Callbacks description:
+ *
+ * -init: request to initialize new table instance.
+ * typedef int (ta_init)(struct ip_fw_chain *ch, void **ta_state,
+ *     struct table_info *ti, char *data, uint8_t tflags);
+ * MANDATORY, unlocked. (M_WAITOK). Returns 0 on success.
+ *
+ *  Allocate all structures needed for normal operations.
+ *  * Caller may want to parse @data for some algo-specific
+ *    options provided by userland.
+ *  * Caller may want to save configuration state pointer to @ta_state
+ *  * Caller needs to save desired runtime structure pointer(s)
+ *    inside @ti fields. Note that it is not correct to save
+ *    @ti pointer at this moment. Use -change_ti hook for that.
+ *  * Caller has to fill in ti->lookup to appropriate function
+ *    pointer.
+ *
+ *
+ *
+ * -destroy: request to destroy table instance.
+ * typedef void (ta_destroy)(void *ta_state, struct table_info *ti);
+ * MANDATORY, may be locked (UH+WLOCK). (M_NOWAIT).
+ *
+ * Frees all table entries and all tables structures allocated by -init.
+ *
+ *
+ *
+ * -prepare_add: request to allocate state for adding new entry.
+ * typedef int (ta_prepare_add)(struct ip_fw_chain *ch, struct tentry_info *tei,
+ *     void *ta_buf);
+ * MANDATORY, unlocked. (M_WAITOK). Returns 0 on success.
+ *
+ * Buffer ta_buf of size ta->ta_buf_sz may be used to store
+ * allocated state.
+ *
+ *
+ *
+ * -prepare_del: request to set state for deleting existing entry.
+ * typedef int (ta_prepare_del)(struct ip_fw_chain *ch, struct tentry_info *tei,
+ *     void *ta_buf);
+ * MANDATORY, locked, UH. (M_NOWAIT). Returns 0 on success.
+ *
+ * Buffer ta_buf of size ta->ta_buf_sz may be used to store
+ * allocated state. Caller should use on-stack ta_buf allocation
+ * instead of doing malloc().
+ *
+ *
+ *
+ * -add: request to insert new entry into runtime/config structures.
+ *  typedef int (ta_add)(void *ta_state, struct table_info *ti,
+ *     struct tentry_info *tei, void *ta_buf, uint32_t *pnum);
+ * MANDATORY, UH+WLOCK. (M_NOWAIT). Returns 0 on success.
+ *
+ * Insert new entry using previously-allocated state in @ta_buf.
+ * * @tei may have the following flags:
+ *   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:
+ *   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.
+ *   entry exists: return EEXIST
+ *   entry not found: return ENOENT
+ *   other error: return non-zero error code.
+ *
+ *
+ *
+ * -del: request to delete existing entry from runtime/config structures.
+ *  typedef int (ta_del)(void *ta_state, struct table_info *ti,
+ *     struct tentry_info *tei, void *ta_buf, uint32_t *pnum);
+ *  MANDATORY, UH+WLOCK. (M_NOWAIT). Returns 0 on success.
+ *
+ *  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 not found: return ENOENT
+ *   other error: return non-zero error code.
+ *
+ *
+ *
+ * -flush_entry: flush entry state created by -prepare_add / -del / others
+ *  typedef void (ta_flush_entry)(struct ip_fw_chain *ch,
+ *      struct tentry_info *tei, void *ta_buf);
+ *  MANDATORY, may be locked. (M_NOWAIT).
+ *
+ *  Delete state allocated by:
+ *  -prepare_add (-add returned EEXIST|UPDATED)
+ *  -prepare_del (if any)
+ *  -del
+ *  * Caller is required to handle empty @ta_buf correctly.
+ *
+ *
+ * -find_tentry: finds entry specified by key @tei
+ *  typedef int ta_find_tentry(void *ta_state, struct table_info *ti,
+ *      ipfw_obj_tentry *tent);
+ *  OPTIONAL, locked (UH). (M_NOWAIT). Returns 0 on success.
+ *
+ *  Finds entry specified by given key.
+ *  * Caller is requred to do the following:
+ *    entry found: returns 0, export entry to @tent
+ *    entry not found: returns ENOENT
+ *
+ *
+ * -need_modify: checks if @ti has enough space to hold another @count items.
+ *  typedef int (ta_need_modify)(void *ta_state, struct table_info *ti,
+ *      uint32_t count, uint64_t *pflags);
+ *  MANDATORY, locked (UH). (M_NOWAIT). Returns 0 if has.
+ *
+ *  Checks if given table has enough space to add @count items without
+ *  resize. Caller may use @pflags to store desired modification data.
+ *
+ *
+ *
+ * -prepare_mod: allocate structures for table modification.
+ *  typedef int (ta_prepare_mod)(void *ta_buf, uint64_t *pflags);
+ * MANDATORY, unlocked. (M_WAITOK). Returns 0 on success.
+ *
+ * Allocate all needed state for table modification. Caller
+ * should use `struct mod_item` to store new state in @ta_buf.
+ * Up to TA_BUF_SZ (128 bytes) can be stored in @ta_buf.
+ * 
+ *
+ *
+ * -fill_mod: copy some data to new state/
+ *  typedef int (ta_fill_mod)(void *ta_state, struct table_info *ti,
+ *      void *ta_buf, uint64_t *pflags);
+ * MANDATORY, locked (UH). (M_NOWAIT). Returns 0 on success.
+ *
+ * Copy as much data as we can to minimize changes under WLOCK.
+ * For example, array can be merged inside this callback.
+ *
+ *
+ *
+ * -modify: perform final modification.
+ *  typedef void (ta_modify)(void *ta_state, struct table_info *ti,
+ *      void *ta_buf, uint64_t pflags);
+ * MANDATORY, locked (UH+WLOCK). (M_NOWAIT). 
+ *
+ * Performs all changes necessary to switch to new structures.
+ * * Caller should save old pointers to @ta_buf storage.
+ *
+ *
+ *
+ * -flush_mod: flush table modification state.
+ *  typedef void (ta_flush_mod)(void *ta_buf);
+ * MANDATORY, unlocked. (M_WAITOK).
+ *
+ * Performs flush for the following:
+ *   - prepare_mod (modification was not necessary)
+ *   - modify (for the old state)
+ *
+ *
+ *
+ * -change_gi: monitor table info pointer changes
+ * typedef void (ta_change_ti)(void *ta_state, struct table_info *ti);
+ * OPTIONAL, locked (UH). (M_NOWAIT).
+ *
+ * Called on @ti pointer changed. Called immediately after -init
+ * to set initial state.
+ *
+ *
+ *
+ * -foreach: calls @f for each table entry
+ *  typedef void ta_foreach(void *ta_state, struct table_info *ti,
+ *      ta_foreach_f *f, void *arg);
+ * MANDATORY, locked(UH). (M_NOWAIT).
+ *
+ * Runs callback with specified argument for each table entry,
+ * Typically used for dumping table entries.
+ *
+ *
+ *
+ * -dump_tentry: dump table entry in current @tentry format.
+ *  typedef int ta_dump_tentry(void *ta_state, struct table_info *ti, void *e,
+ *      ipfw_obj_tentry *tent);
+ * MANDATORY, locked(UH). (M_NOWAIT). Returns 0 on success.
+ *
+ * Dumps entry @e to @tent.
+ *
+ *
+ * -print_config: prints custom algoritm options into buffer.
+ *  typedef void (ta_print_config)(void *ta_state, struct table_info *ti,
+ *      char *buf, size_t bufsize);
+ * OPTIONAL. locked(UH). (M_NOWAIT).
+ *
+ * Prints custom algorithm options in the format suitable to pass
+ * back to -init callback.
+ *
+ *
+ *
+ * -dump_tinfo: dumps algo-specific info.
+ *  typedef void ta_dump_tinfo(void *ta_state, struct table_info *ti,
+ *      ipfw_ta_tinfo *tinfo);
+ * OPTIONAL. locked(UH). (M_NOWAIT).
+ *
+ * Dumps options like items size/hash size, etc.
+ */
+
 static MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables");
 
 /*
@@ -587,7 +802,7 @@ ta_flush_radix_entry(struct ip_fw_chain 
 }
 
 static int
-ta_has_space_radix(void *ta_state, struct table_info *ti, uint32_t count,
+ta_need_modify_radix(void *ta_state, struct table_info *ti, uint32_t count,
     uint64_t *pflags)
 {
 
@@ -597,7 +812,7 @@ ta_has_space_radix(void *ta_state, struc
 	 * but we don't have any API to call (and we don't known which
 	 * sizes do we need).
 	 */
-	return (1);
+	return (0);
 }
 
 struct table_algo cidr_radix = {
@@ -616,7 +831,7 @@ struct table_algo cidr_radix = {
 	.dump_tentry	= ta_dump_radix_tentry,
 	.find_tentry	= ta_find_radix_tentry,
 	.dump_tinfo	= ta_dump_radix_tinfo,
-	.has_space	= ta_has_space_radix,
+	.need_modify	= ta_need_modify_radix,
 };
 
 
@@ -1357,7 +1572,7 @@ ta_flush_chash_entry(struct ip_fw_chain 
  */
 
 static int
-ta_has_space_chash(void *ta_state, struct table_info *ti, uint32_t count,
+ta_need_modify_chash(void *ta_state, struct table_info *ti, uint32_t count,
     uint64_t *pflags)
 {
 	struct chash_cfg *cfg;
@@ -1379,10 +1594,10 @@ ta_has_space_chash(void *ta_state, struc
 
 	if (data != 0) {
 		*pflags = data;
-		return (0);
+		return (1);
 	}
 
-	return (1);
+	return (0);
 }
 
 /*
@@ -1434,7 +1649,7 @@ ta_fill_mod_chash(void *ta_state, struct
 /*
  * Switch old & new arrays.
  */
-static int
+static void
 ta_modify_chash(void *ta_state, struct table_info *ti, void *ta_buf,
     uint64_t pflags)
 {
@@ -1495,8 +1710,6 @@ ta_modify_chash(void *ta_state, struct t
 	/* Update lower 32 bits with new values */
 	ti->data &= 0xFFFFFFFF00000000;
 	ti->data |= log2(cfg->size4) << 8 | log2(cfg->size6);
-
-	return (0);
 }
 
 /*
@@ -1530,7 +1743,7 @@ struct table_algo cidr_hash = {
 	.find_tentry	= ta_find_chash_tentry,
 	.print_config	= ta_print_chash_config,
 	.dump_tinfo	= ta_dump_chash_tinfo,
-	.has_space	= ta_has_space_chash,
+	.need_modify	= ta_need_modify_chash,
 	.prepare_mod	= ta_prepare_mod_chash,
 	.fill_mod	= ta_fill_mod_chash,
 	.modify		= ta_modify_chash,
@@ -2033,7 +2246,7 @@ if_notifier(struct ip_fw_chain *ch, void
  */
 
 static int
-ta_has_space_ifidx(void *ta_state, struct table_info *ti, uint32_t count,
+ta_need_modify_ifidx(void *ta_state, struct table_info *ti, uint32_t count,
     uint64_t *pflags)
 {
 	struct iftable_cfg *cfg;
@@ -2047,10 +2260,10 @@ ta_has_space_ifidx(void *ta_state, struc
 
 	if (size != cfg->size) {
 		*pflags = size;
-		return (0);
+		return (1);
 	}
 
-	return (1);
+	return (0);
 }
 
 /*
@@ -2098,7 +2311,7 @@ ta_fill_mod_ifidx(void *ta_state, struct
 /*
  * Switch old & new arrays.
  */
-static int
+static void
 ta_modify_ifidx(void *ta_state, struct table_info *ti, void *ta_buf,
     uint64_t pflags)
 {
@@ -2115,8 +2328,6 @@ ta_modify_ifidx(void *ta_state, struct t
 	ti->state = icfg->main_ptr;
 
 	mi->main_ptr = old_ptr;
-
-	return (0);
 }
 
 /*
@@ -2220,7 +2431,7 @@ struct table_algo iface_idx = {
 	.dump_tentry	= ta_dump_ifidx_tentry,
 	.find_tentry	= ta_find_ifidx_tentry,
 	.dump_tinfo	= ta_dump_ifidx_tinfo,
-	.has_space	= ta_has_space_ifidx,
+	.need_modify	= ta_need_modify_ifidx,
 	.prepare_mod	= ta_prepare_mod_ifidx,
 	.fill_mod	= ta_fill_mod_ifidx,
 	.modify		= ta_modify_ifidx,
@@ -2460,7 +2671,7 @@ ta_flush_numarray_entry(struct ip_fw_cha
  */
 
 static int
-ta_has_space_numarray(void *ta_state, struct table_info *ti, uint32_t count,
+ta_need_modify_numarray(void *ta_state, struct table_info *ti, uint32_t count,
     uint64_t *pflags)
 {
 	struct numarray_cfg *cfg;
@@ -2474,10 +2685,10 @@ ta_has_space_numarray(void *ta_state, st
 
 	if (size != cfg->size) {
 		*pflags = size;
-		return (0);
+		return (1);
 	}
 
-	return (1);
+	return (0);
 }
 
 /*
@@ -2525,7 +2736,7 @@ ta_fill_mod_numarray(void *ta_state, str
 /*
  * Switch old & new arrays.
  */
-static int
+static void
 ta_modify_numarray(void *ta_state, struct table_info *ti, void *ta_buf,
     uint64_t pflags)
 {
@@ -2542,8 +2753,6 @@ ta_modify_numarray(void *ta_state, struc
 	ti->state = cfg->main_ptr;
 
 	mi->main_ptr = old_ptr;
-
-	return (0);
 }
 
 /*
@@ -2622,7 +2831,7 @@ struct table_algo number_array = {
 	.dump_tentry	= ta_dump_numarray_tentry,
 	.find_tentry	= ta_find_numarray_tentry,
 	.dump_tinfo	= ta_dump_numarray_tinfo,
-	.has_space	= ta_has_space_numarray,
+	.need_modify	= ta_need_modify_numarray,
 	.prepare_mod	= ta_prepare_mod_numarray,
 	.fill_mod	= ta_fill_mod_numarray,
 	.modify		= ta_modify_numarray,
@@ -3186,7 +3395,7 @@ ta_flush_fhash_entry(struct ip_fw_chain 
  */
 
 static int
-ta_has_space_fhash(void *ta_state, struct table_info *ti, uint32_t count,
+ta_need_modify_fhash(void *ta_state, struct table_info *ti, uint32_t count,
     uint64_t *pflags)
 {
 	struct fhash_cfg *cfg;
@@ -3195,10 +3404,10 @@ ta_has_space_fhash(void *ta_state, struc
 
 	if (cfg->items > cfg->size && cfg->size < 65536) {
 		*pflags = cfg->size * 2;
-		return (0);
+		return (1);
 	}
 
-	return (1);
+	return (0);
 }
 
 /*
@@ -3240,7 +3449,7 @@ ta_fill_mod_fhash(void *ta_state, struct
 /*
  * Switch old & new arrays.
  */
-static int
+static void
 ta_modify_fhash(void *ta_state, struct table_info *ti, void *ta_buf,
     uint64_t pflags)
 {
@@ -3255,13 +3464,9 @@ ta_modify_fhash(void *ta_state, struct t
 	mi = (struct mod_item *)ta_buf;
 	cfg = (struct fhash_cfg *)ta_state;
 
-	/* Check which hash we need to grow and do we still need that */
 	old_size = cfg->size;
 	old_head = ti->state;
 
-	if (old_size >= mi->size)
-		return (0);
-
 	new_head = (struct fhashbhead *)mi->main_ptr;
 	for (i = 0; i < old_size; i++) {
 		SLIST_FOREACH_SAFE(ent, &old_head[i], next, ent_next) {
@@ -3276,8 +3481,6 @@ ta_modify_fhash(void *ta_state, struct t
 	cfg->size = mi->size;
 
 	mi->main_ptr = old_head;
-
-	return (0);
 }
 
 /*
@@ -3309,7 +3512,7 @@ struct table_algo flow_hash = {
 	.dump_tentry	= ta_dump_fhash_tentry,
 	.find_tentry	= ta_find_fhash_tentry,
 	.dump_tinfo	= ta_dump_fhash_tinfo,
-	.has_space	= ta_has_space_fhash,
+	.need_modify	= ta_need_modify_fhash,
 	.prepare_mod	= ta_prepare_mod_fhash,
 	.fill_mod	= ta_fill_mod_fhash,
 	.modify		= ta_modify_fhash,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53ea200c.64ff.24e31b86>