From owner-svn-src-projects@FreeBSD.ORG Tue Aug 12 14:09:16 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id EDB0DE3B for ; Tue, 12 Aug 2014 14:09:16 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DBB872527 for ; Tue, 12 Aug 2014 14:09:16 +0000 (UTC) Received: from melifaro (uid 1268) (envelope-from melifaro@FreeBSD.org) id 64ff by svn.freebsd.org (DragonFly Mail Agent v0.9+); Tue, 12 Aug 2014 14:09:16 +0000 From: Alexander V. Chernikov Date: Tue, 12 Aug 2014 14:09:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r269876 - projects/ipfw/sys/netpfil/ipfw X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <53ea200c.64ff.24e31b86@svn.freebsd.org> X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Aug 2014 14:09:17 -0000 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 #include + +/* + * 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,