svn commit: r267542 - in projects/ipfw/sys: netinet netpfil/ipfw
Alexander V. Chernikov
melifaro at FreeBSD.org
Mon Jun 16 13:05:09 UTC 2014
Author: melifaro
Date: Mon Jun 16 13:05:07 2014
New Revision: 267542
URL: http://svnweb.freebsd.org/changeset/base/267542
Log:
* Add IP_FW_TABLE_XCREATE / IP_FW_TABLE_XMODIFY opcodes.
* Add 'algoname' string to ipfw_xtable_info permitting to specify lookup
algoritm with parameters.
* Rework part of ipfw_rewrite_table_uidx()
Sponsored by: Yandex LLC
Modified:
projects/ipfw/sys/netinet/ip_fw.h
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.c
projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
Modified: projects/ipfw/sys/netinet/ip_fw.h
==============================================================================
--- projects/ipfw/sys/netinet/ip_fw.h Mon Jun 16 12:37:10 2014 (r267541)
+++ projects/ipfw/sys/netinet/ip_fw.h Mon Jun 16 13:05:07 2014 (r267542)
@@ -81,10 +81,12 @@ typedef struct _ip_fw3_opheader {
#define IP_FW_TABLE_XGETSIZE 88 /* get table size (deprecated) */
#define IP_FW_TABLE_XLIST 89 /* list table contents */
#define IP_FW_TABLE_XDESTROY 90 /* destroy table */
-#define IP_FW_TABLES_XGETSIZE 91 /* get size for table/etc list */
-#define IP_FW_TABLES_XLIST 92 /* list all objects of given type */
-#define IP_FW_TABLE_XINFO 93 /* request info for one object */
-#define IP_FW_TABLE_XFLUSH 94 /* flush data for given object */
+#define IP_FW_TABLES_XGETSIZE 91 /* get size for tables list */
+#define IP_FW_TABLES_XLIST 92 /* list all tables */
+#define IP_FW_TABLE_XINFO 93 /* request info for one table */
+#define IP_FW_TABLE_XFLUSH 94 /* flush table data */
+#define IP_FW_TABLE_XCREATE 95 /* create new table */
+#define IP_FW_TABLE_XMODIFY 96 /* modify existing table */
/*
* Usage guidelines:
@@ -693,7 +695,7 @@ typedef struct _ipfw_obj_ntlv {
typedef struct _ipfw_xtable_info {
uint8_t type; /* table type (cidr,iface,..) */
- uint8_t ftype; /* format table type */
+ uint8_t ftype; /* table value format type */
uint8_t atype; /* algorithm type */
uint8_t spare0;
uint32_t set; /* set table is in */
@@ -702,6 +704,7 @@ typedef struct _ipfw_xtable_info {
uint32_t count; /* Number of records */
uint32_t size; /* Total size of records */
char tablename[64]; /* table name */
+ char algoname[32]; /* algorithm name */
} ipfw_xtable_info;
#define IPFW_OBJTYPE_TABLE 1
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h Mon Jun 16 12:37:10 2014 (r267541)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h Mon Jun 16 13:05:07 2014 (r267542)
@@ -362,6 +362,8 @@ struct named_object *ipfw_objhash_lookup
uint32_t set, char *name);
struct named_object *ipfw_objhash_lookup_idx(struct namedobj_instance *ni,
uint32_t set, uint16_t idx);
+int ipfw_objhash_same_name(struct namedobj_instance *ni, struct named_object *a,
+ struct named_object *b);
void ipfw_objhash_add(struct namedobj_instance *ni, struct named_object *no);
void ipfw_objhash_del(struct namedobj_instance *ni, struct named_object *no);
uint32_t ipfw_objhash_count(struct namedobj_instance *ni);
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c Mon Jun 16 12:37:10 2014 (r267541)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c Mon Jun 16 13:05:07 2014 (r267542)
@@ -1172,6 +1172,14 @@ ipfw_ctl(struct sockopt *sopt)
break;
/*--- TABLE opcodes ---*/
+ case IP_FW_TABLE_XCREATE: /* IP_FW3 */
+ case IP_FW_TABLE_XMODIFY: /* IP_FW3 */
+ if (opt == IP_FW_TABLE_XCREATE)
+ error = ipfw_create_table(chain, sopt, op3);
+ else
+ error= ipfw_modify_table(chain, sopt, op3);
+ break;
+
case IP_FW_TABLE_XDESTROY: /* IP_FW3 */
case IP_FW_TABLE_XFLUSH: /* IP_FW3 */
{
@@ -1705,6 +1713,17 @@ ipfw_objhash_lookup_idx(struct namedobj_
return (NULL);
}
+int
+ipfw_objhash_same_name(struct namedobj_instance *ni, struct named_object *a,
+ struct named_object *b)
+{
+
+ if ((strcmp(a->name, b->name) == 0) && a->set == b->set)
+ return (1);
+
+ return (0);
+}
+
void
ipfw_objhash_add(struct namedobj_instance *ni, struct named_object *no)
{
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c Mon Jun 16 12:37:10 2014 (r267541)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c Mon Jun 16 13:05:07 2014 (r267542)
@@ -69,8 +69,9 @@ __FBSDID("$FreeBSD$");
* `ta->atype` represents exact lookup algorithm.
* For example, we can use more efficient search schemes if we plan
* to use some specific table for storing host-routes only.
- * `ftype` is pure userland field helping to properly format table data
- * e.g. "value is IPv4 nexthop" or "key is port number"
+ * `ftype` (at the moment )is pure userland field helping to properly
+ * format value data e.g. "value is IPv4 nexthop" or "value is DSCP"
+ * or "value is port".
*
*/
struct table_config {
@@ -95,7 +96,7 @@ struct tables_config {
static struct table_config *find_table(struct namedobj_instance *ni,
struct tid_info *ti);
static struct table_config *alloc_table_config(struct namedobj_instance *ni,
- struct tid_info *ti, struct table_algo *ta);
+ struct tid_info *ti, struct table_algo *ta, char *adata);
static void free_table_config(struct namedobj_instance *ni,
struct table_config *tc);
static void link_table(struct ip_fw_chain *chain, struct table_config *tc);
@@ -114,7 +115,7 @@ static int ipfw_dump_table_v1(struct ip_
ip_fw3_opheader *op3, size_t valsize);
static struct table_algo *find_table_algo(struct tables_config *tableconf,
- struct tid_info *ti);
+ struct tid_info *ti, char *name);
#define CHAIN_TO_TCFG(chain) ((struct tables_config *)(chain)->tblcfg)
#define CHAIN_TO_NI(chain) (CHAIN_TO_TCFG(chain)->namehash)
@@ -161,10 +162,10 @@ ipfw_add_table_entry(struct ip_fw_chain
tc_new = NULL;
if (ta == NULL) {
/* Table not found. We have to create new one */
- if ((ta = find_table_algo(CHAIN_TO_TCFG(ch), ti)) == NULL)
+ if ((ta = find_table_algo(CHAIN_TO_TCFG(ch), ti, NULL)) == NULL)
return (ENOTSUP);
- tc_new = alloc_table_config(ni, ti, ta);
+ tc_new = alloc_table_config(ni, ti, ta, NULL);
if (tc_new == NULL)
return (ENOMEM);
}
@@ -330,9 +331,10 @@ ipfw_flush_table(struct ip_fw_chain *ch,
/*
* Stage 2: allocate new table instance using same algo.
+ * TODO: pass startup parametes somehow.
*/
memset(&ti_new, 0, sizeof(struct table_info));
- if ((error = ta->init(&astate_new, &ti_new)) != 0) {
+ if ((error = ta->init(&astate_new, &ti_new, NULL)) != 0) {
IPFW_UH_WLOCK(ch);
tc->no.refcnt--;
IPFW_UH_WUNLOCK(ch);
@@ -885,6 +887,99 @@ ipfw_dump_table_v0(struct ip_fw_chain *c
}
/*
+ * High-level setsockopt cmds
+ */
+int
+ipfw_modify_table(struct ip_fw_chain *ch, struct sockopt *sopt,
+ ip_fw3_opheader *op3)
+{
+
+ return (ENOTSUP);
+}
+
+/*
+ * Creates new table.
+ * Data layout:
+ * Request: [ ipfw_obj_header ipfw_xtable_info ]
+ *
+ * Returns 0 on success
+ */
+int
+ipfw_create_table(struct ip_fw_chain *ch, struct sockopt *sopt,
+ ip_fw3_opheader *op3)
+{
+ struct _ipfw_obj_header *oh;
+ ipfw_xtable_info *i;
+ char *tname, *aname;
+ struct tid_info ti;
+ struct namedobj_instance *ni;
+ struct table_config *tc;
+ struct table_algo *ta;
+ uint16_t kidx;
+
+ if (sopt->sopt_valsize < sizeof(*oh) + sizeof(ipfw_xtable_info))
+ return (EINVAL);
+
+ oh = (struct _ipfw_obj_header *)op3;
+ i = (ipfw_xtable_info *)(oh + 1);
+
+ /*
+ * Verify user-supplied strings.
+ * Check for null-terminated/zero-lenght strings/
+ */
+ tname = i->tablename;
+ aname = i->algoname;
+ if (strnlen(tname, sizeof(i->tablename)) == sizeof(i->tablename) ||
+ tname[0] == '\0' ||
+ strnlen(aname, sizeof(i->algoname)) == sizeof(i->algoname))
+ return (EINVAL);
+
+ if (aname[0] == '\0') {
+ /* Use default algorithm */
+ aname = NULL;
+ }
+
+ objheader_to_ti(oh, &ti);
+
+ ni = CHAIN_TO_NI(ch);
+
+ IPFW_UH_RLOCK(ch);
+ if ((tc = find_table(ni, &ti)) != NULL) {
+ IPFW_UH_RUNLOCK(ch);
+ return (EEXIST);
+ }
+ ta = find_table_algo(CHAIN_TO_TCFG(ch), &ti, aname);
+ IPFW_UH_RUNLOCK(ch);
+
+ if (ta == NULL)
+ return (ENOTSUP);
+
+ if ((tc = alloc_table_config(ni, &ti, ta, aname)) == NULL)
+ return (ENOMEM);
+
+ IPFW_UH_WLOCK(ch);
+ if (ipfw_objhash_alloc_idx(ni, ti.set, &kidx) != 0) {
+ IPFW_UH_WUNLOCK(ch);
+ printf("Unable to allocate table index for table %s in set %u."
+ " Consider increasing net.inet.ip.fw.tables_max",
+ tname, ti.set);
+ free_table_config(ni, tc);
+ return (EBUSY);
+ }
+
+ tc->no.kidx = kidx;
+
+ IPFW_WLOCK(ch);
+ link_table(ch, tc);
+ IPFW_WUNLOCK(ch);
+
+ IPFW_UH_WUNLOCK(ch);
+
+ return (0);
+}
+
+
+/*
* Checks if supplied buffer size is "reasonable".
* Permit valsize between current needed size and
* 2x needed size + 1
@@ -1059,7 +1154,9 @@ ipfw_dump_table_legacy(struct ip_fw_chai
return (0);
}
-
+/*
+ * Dumps table entry in eXtended format (current).
+ */
static int
dump_table_xentry(void *e, void *arg)
{
@@ -1089,11 +1186,13 @@ dump_table_xentry(void *e, void *arg)
*/
/*
- * Finds algoritm by index or table type
+ * Finds algoritm by index, table type or supplied name
*/
static struct table_algo *
-find_table_algo(struct tables_config *tcfg, struct tid_info *ti)
+find_table_algo(struct tables_config *tcfg, struct tid_info *ti, char *name)
{
+ int i, l;
+ struct table_algo *ta;
/* Search by index */
if (ti->atype != 0) {
@@ -1102,6 +1201,30 @@ find_table_algo(struct tables_config *tc
return (tcfg->algo[ti->atype]);
}
+ /* Search by name if supplied */
+ if (name != NULL) {
+ /* TODO: better search */
+ for (i = 1; i <= tcfg->algo_count; i++) {
+ ta = tcfg->algo[i];
+
+ /*
+ * One can supply additional algorithm
+ * parameters so we compare only the first word
+ * of supplied name:
+ * 'hash_cidr hsize=32'
+ * '^^^^^^^^^'
+ *
+ */
+ l = strlen(ta->name);
+ if (strncmp(name, ta->name, l) == 0) {
+ if (name[l] == '\0' || name[l] == ' ')
+ return (ta);
+ }
+ }
+
+ return (NULL);
+ }
+
/* Search by type */
switch (ti->type) {
case IPFW_TABLE_CIDR:
@@ -1272,7 +1395,7 @@ find_table(struct namedobj_instance *ni,
static struct table_config *
alloc_table_config(struct namedobj_instance *ni, struct tid_info *ti,
- struct table_algo *ta)
+ struct table_algo *ta, char *aname)
{
char *name, bname[16];
struct table_config *tc;
@@ -1300,7 +1423,7 @@ alloc_table_config(struct namedobj_insta
}
/* Preallocate data structures for new tables */
- error = ta->init(&tc->astate, &tc->ti);
+ error = ta->init(&tc->astate, &tc->ti, aname);
if (error != 0) {
free(tc, M_IPFW);
return (NULL);
@@ -1371,45 +1494,89 @@ unlink_table(struct ip_fw_chain *ch, str
/*
* Finds named object by @uidx number.
* Refs found object, allocate new index for non-existing object.
- * Fills in @pidx with userland/kernel indexes.
+ * Fills in @oib with userland/kernel indexes.
+ * First free oidx pointer is saved back in @oib.
*
* Returns 0 on success.
*/
static int
-bind_table(struct namedobj_instance *ni, struct rule_check_info *ci,
- struct obj_idx *pidx, struct tid_info *ti)
+bind_table_rule(struct ip_fw_chain *ch, struct ip_fw *rule,
+ struct rule_check_info *ci, struct obj_idx **oib, struct tid_info *ti)
{
struct table_config *tc;
+ struct namedobj_instance *ni;
+ struct named_object *no;
+ int error, l, cmdlen;
+ ipfw_insn *cmd;
+ struct obj_idx *pidx, *p;
+
+ pidx = *oib;
+ l = rule->cmd_len;
+ cmd = rule->cmd;
+ cmdlen = 0;
+ error = 0;
- pidx->uidx = ti->uidx;
- pidx->type = ti->type;
+ IPFW_UH_WLOCK(ch);
+ ni = CHAIN_TO_NI(ch);
- tc = find_table(ni, ti);
+ for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
+ cmdlen = F_LEN(cmd);
- if (tc == NULL) {
- /* Try to acquire refcount */
+ if (classify_table_opcode(cmd, &ti->uidx, &ti->type) != 0)
+ continue;
+
+ pidx->uidx = ti->uidx;
+ pidx->type = ti->type;
+
+ if ((tc = find_table(ni, ti)) != NULL) {
+ if (tc->no.type != ti->type) {
+ /* Incompatible types */
+ error = EINVAL;
+ break;
+ }
+
+ /* Reference found table and save kidx */
+ tc->no.refcnt++;
+ pidx->kidx = tc->no.kidx;
+ pidx++;
+ continue;
+ }
+
+ /* Table not found. Allocate new index and save for later */
if (ipfw_objhash_alloc_idx(ni, ti->set, &pidx->kidx) != 0) {
printf("Unable to allocate table index in set %u."
" Consider increasing net.inet.ip.fw.tables_max",
- ti->set);
- return (EBUSY);
+ ti->set);
+ error = EBUSY;
+ break;
}
- pidx->new = 1;
ci->new_tables++;
-
- return (0);
+ pidx->new = 1;
+ pidx++;
}
- /* Check if table type if valid first */
- if (tc->no.type != ti->type)
- return (EINVAL);
+ if (error != 0) {
+ /* Unref everything we have already done */
+ for (p = *oib; p < pidx; p++) {
+ if (p->new != 0) {
+ ipfw_objhash_free_idx(ni, ci->tableset,p->kidx);
+ continue;
+ }
- tc->no.refcnt++;
+ /* Find & unref by existing idx */
+ no = ipfw_objhash_lookup_idx(ni, ci->tableset, p->kidx);
+ KASSERT(no != NULL, ("Ref'd table %d disappeared",
+ p->kidx));
- pidx->kidx = tc->no.kidx;
+ no->refcnt--;
+ }
+ }
+ IPFW_UH_WUNLOCK(ch);
- return (0);
+ *oib = pidx;
+
+ return (error);
}
/*
@@ -1477,24 +1644,27 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
struct table_algo *ta;
struct namedobj_instance *ni;
struct named_object *no, *no_n, *no_tmp;
- struct obj_idx *pidx, *p, *oib;
+ struct obj_idx *p, *pidx_first, *pidx_last;
struct namedobjects_head nh;
struct tid_info ti;
ni = CHAIN_TO_NI(chain);
+ /* Prepare queue to store configs */
+ TAILQ_INIT(&nh);
+
/*
* Prepare an array for storing opcode indices.
* Use stack allocation by default.
*/
if (ci->table_opcodes <= (sizeof(ci->obuf)/sizeof(ci->obuf[0]))) {
/* Stack */
- pidx = ci->obuf;
+ pidx_first = ci->obuf;
} else
- pidx = malloc(ci->table_opcodes * sizeof(struct obj_idx),
+ pidx_first = malloc(ci->table_opcodes * sizeof(struct obj_idx),
M_IPFW, M_WAITOK | M_ZERO);
- oib = pidx;
+ pidx_last = pidx_first;
error = 0;
type = 0;
@@ -1508,72 +1678,24 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
ti.tlen = ci->tlen;
/*
- * Stage 1: reference existing tables and determine number
- * of tables we need to allocate
+ * Stage 1: reference existing tables, determine number
+ * of tables we need to allocate and allocate indexes for each.
*/
- IPFW_UH_WLOCK(chain);
-
- l = ci->krule->cmd_len;
- cmd = ci->krule->cmd;
- cmdlen = 0;
- for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
- cmdlen = F_LEN(cmd);
-
- if (classify_table_opcode(cmd, &ti.uidx, &ti.type) != 0)
- continue;
-
- /*
- * Got table opcode with necessary info.
- * Try to reference existing tables and allocate
- * indices for non-existing one while holding write lock.
- */
- if ((error = bind_table(ni, ci, pidx, &ti)) != 0) {
- printf("error!\n");
- break;
- }
-
- /*
- * @pidx stores either existing ref'd table id or new one.
- * Move to next index
- */
-
- pidx++;
- }
+ error = bind_table_rule(chain, ci->krule, ci, &pidx_last, &ti);
if (error != 0) {
- /* Unref everything we have already done */
- for (p = oib; p < pidx; p++) {
- if (p->new != 0) {
- ipfw_objhash_free_idx(ni, ci->tableset,p->kidx);
- continue;
- }
-
- /* Find & unref by existing idx */
- no = ipfw_objhash_lookup_idx(ni, ci->tableset, p->kidx);
- KASSERT(no!=NULL, ("Ref'd table %d disappeared",
- p->kidx));
-
- no->refcnt--;
- }
-
- IPFW_UH_WUNLOCK(chain);
-
- if (oib != ci->obuf)
- free(oib, M_IPFW);
+ if (pidx_first != ci->obuf)
+ free(pidx_first, M_IPFW);
return (error);
}
- IPFW_UH_WUNLOCK(chain);
-
/*
* Stage 2: allocate table configs for every non-existent table
*/
- /* Prepare queue to store configs */
- TAILQ_INIT(&nh);
if (ci->new_tables > 0) {
- for (p = oib; p < pidx; p++) {
+ for (p = pidx_first; p < pidx_last; p++) {
if (p->new == 0)
continue;
@@ -1582,12 +1704,12 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
ti.type = p->type;
ti.atype = 0;
- ta = find_table_algo(CHAIN_TO_TCFG(chain), &ti);
+ ta = find_table_algo(CHAIN_TO_TCFG(chain), &ti, NULL);
if (ta == NULL) {
error = ENOTSUP;
goto free;
}
- tc = alloc_table_config(ni, &ti, ta);
+ tc = alloc_table_config(ni, &ti, ta, NULL);
if (tc == NULL) {
error = ENOMEM;
@@ -1607,7 +1729,7 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
*/
TAILQ_FOREACH(no, &nh, nn_next) {
TAILQ_FOREACH(no_tmp, &nh, nn_next) {
- if (strcmp(no->name, no_tmp->name) != 0)
+ if (ipfw_objhash_same_name(ni, no, no_tmp) == 0)
continue;
if (no->type != no_tmp->type) {
error = EINVAL;
@@ -1649,7 +1771,6 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
* We have to rollback everything.
*/
IPFW_UH_WUNLOCK(chain);
-
goto free;
}
@@ -1662,24 +1783,28 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
IPFW_WLOCK(chain);
TAILQ_FOREACH_SAFE(no, &nh, nn_next, no_tmp) {
no_n = ipfw_objhash_lookup_name(ni, no->set, no->name);
- if (no_n != NULL) {
- /* Increase refcount for existing table */
- no_n->refcnt++;
- /* Keep oib array in sync: update kindx */
- for (p = oib; p < pidx; p++) {
- if (p->kidx == no->kidx) {
- p->kidx = no_n->kidx;
- break;
- }
- }
+ if (no_n == NULL) {
+ /* New table. Attach to runtime hash */
+ TAILQ_REMOVE(&nh, no, nn_next);
+ link_table(chain, (struct table_config *)no);
continue;
}
- /* New table. Attach to runtime hash */
- TAILQ_REMOVE(&nh, no, nn_next);
-
- link_table(chain, (struct table_config *)no);
+ /*
+ * Newly-allocated table with the same type.
+ * Reference it and update out @pidx array
+ * rewrite info.
+ */
+ no_n->refcnt++;
+ /* Keep oib array in sync: update kidx */
+ for (p = pidx_first; p < pidx_last; p++) {
+ if (p->kidx != no->kidx)
+ continue;
+ /* Update kidx */
+ p->kidx = no_n->kidx;
+ break;
+ }
}
IPFW_WUNLOCK(chain);
}
@@ -1688,14 +1813,14 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
l = ci->krule->cmd_len;
cmd = ci->krule->cmd;
cmdlen = 0;
- pidx = oib;
+ p = pidx_first;
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
if (classify_table_opcode(cmd, &uidx, &type) != 0)
continue;
- update_table_opcode(cmd, pidx->kidx);
- pidx++;
+ update_table_opcode(cmd, p->kidx);
+ p++;
}
IPFW_UH_WUNLOCK(chain);
@@ -1706,11 +1831,20 @@ ipfw_rewrite_table_uidx(struct ip_fw_cha
* Stage 4: free resources
*/
free:
- TAILQ_FOREACH_SAFE(no, &nh, nn_next, no_tmp)
- free_table_config(ni, tc);
+ if (!TAILQ_EMPTY(&nh)) {
+ /* Free indexes first */
+ IPFW_UH_WLOCK(chain);
+ TAILQ_FOREACH_SAFE(no, &nh, nn_next, no_tmp) {
+ ipfw_objhash_free_idx(ni, ci->tableset, no->kidx);
+ }
+ IPFW_UH_WUNLOCK(chain);
+ /* Free configs */
+ TAILQ_FOREACH_SAFE(no, &nh, nn_next, no_tmp)
+ free_table_config(ni, tc);
+ }
- if (oib != ci->obuf)
- free(oib, M_IPFW);
+ if (pidx_first != ci->obuf)
+ free(pidx_first, M_IPFW);
return (error);
}
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h Mon Jun 16 12:37:10 2014 (r267541)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h Mon Jun 16 13:05:07 2014 (r267542)
@@ -50,7 +50,7 @@ struct tentry_info {
uint32_t value; /* value */
};
-typedef int (ta_init)(void **ta_state, struct table_info *ti);
+typedef int (ta_init)(void **ta_state, struct table_info *ti, char *data);
typedef void (ta_destroy)(void *ta_state, struct table_info *ti);
typedef int (ta_prepare_add)(struct tentry_info *tei, void *ta_buf);
typedef int (ta_prepare_del)(struct tentry_info *tei, void *ta_buf);
@@ -69,7 +69,7 @@ typedef int ta_dump_xentry(void *ta_stat
ipfw_table_xentry *xent);
struct table_algo {
- char name[64];
+ char name[16];
int idx;
ta_init *init;
ta_destroy *destroy;
@@ -100,6 +100,11 @@ int ipfw_dump_table(struct ip_fw_chain *
int ipfw_describe_table(struct ip_fw_chain *ch, struct sockopt *sopt,
ip_fw3_opheader *op3, size_t valsize);
+int ipfw_create_table(struct ip_fw_chain *ch, struct sockopt *sopt,
+ ip_fw3_opheader *op3);
+int ipfw_modify_table(struct ip_fw_chain *ch, struct sockopt *sopt,
+ ip_fw3_opheader *op3);
+
int ipfw_destroy_table(struct ip_fw_chain *ch, struct tid_info *ti);
int ipfw_flush_table(struct ip_fw_chain *ch, struct tid_info *ti);
int ipfw_add_table_entry(struct ip_fw_chain *ch, struct tid_info *ti,
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c Mon Jun 16 12:37:10 2014 (r267541)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c Mon Jun 16 13:05:07 2014 (r267542)
@@ -164,7 +164,7 @@ ta_lookup_radix(struct table_info *ti, v
* New table
*/
static int
-ta_init_radix(void **ta_state, struct table_info *ti)
+ta_init_radix(void **ta_state, struct table_info *ti, char *data)
{
if (!rn_inithead(&ti->state, OFF_LEN_INET))
@@ -537,7 +537,7 @@ flush_iface_entry(struct radix_node *rn,
}
static int
-ta_init_iface(void **ta_state, struct table_info *ti)
+ta_init_iface(void **ta_state, struct table_info *ti, char *data)
{
if (!rn_inithead(&ti->xstate, OFF_LEN_IFACE))
More information about the svn-src-projects
mailing list