summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw/tables.c
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2014-07-26 13:37:25 +0000
committermelifaro <melifaro@FreeBSD.org>2014-07-26 13:37:25 +0000
commit505e5ae08158dae524fad92308b69c209a5f69d9 (patch)
tree992bd8b8c50d4af7fe911750b6c929b8a8fe07c6 /sbin/ipfw/tables.c
parentdeb9ca0f18daa165fa9fe29716230066af8c4707 (diff)
downloadFreeBSD-src-505e5ae08158dae524fad92308b69c209a5f69d9.zip
FreeBSD-src-505e5ae08158dae524fad92308b69c209a5f69d9.tar.gz
* Require explicit table creation before use on kernel side.
* Add resize callbacks for upcoming table-based algorithms. Kernel changes: * s/ipfw_modify_table/ipfw_manage_table_ent/ * Simplify add_table_entry(): make table creation a separate piece of code. Do not perform creation if not in "compat" mode. * Add ability to perform modification of algorithm state (like table resize). The following callbacks were added: - prepare_mod (allocate new state, without locks) - fill_mod (UH_WLOCK, copy old state to new one) - modify (UH_WLOCK + WLOCK, switch state) - flush_mod (no locks, flushes allocated data) Given callbacks are called if table modification has been requested by add or delete callbacks. Additional u64 tc->'flags' field was added to pass these requests. * Change add/del table ent format: permit adding/removing multiple entries at once (only 1 supported at the moment). Userland changes: * Auto-create tables with warning
Diffstat (limited to 'sbin/ipfw/tables.c')
-rw-r--r--sbin/ipfw/tables.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c
index 670b8ce..c0393e1 100644
--- a/sbin/ipfw/tables.c
+++ b/sbin/ipfw/tables.c
@@ -465,7 +465,8 @@ static int
table_do_modify_record(int cmd, ipfw_obj_header *oh,
ipfw_obj_tentry *tent, int update)
{
- char xbuf[sizeof(ipfw_obj_header) + sizeof(ipfw_obj_tentry)];
+ ipfw_obj_ctlv *ctlv;
+ char xbuf[sizeof(*oh) + sizeof(ipfw_obj_ctlv) + sizeof(*tent)];
int error;
memset(xbuf, 0, sizeof(xbuf));
@@ -473,8 +474,12 @@ table_do_modify_record(int cmd, ipfw_obj_header *oh,
oh = (ipfw_obj_header *)xbuf;
oh->opheader.version = 1;
- memcpy(oh + 1, tent, sizeof(*tent));
- tent = (ipfw_obj_tentry *)(oh + 1);
+ ctlv = (ipfw_obj_ctlv *)(oh + 1);
+ ctlv->count = 1;
+ ctlv->head.length = sizeof(*ctlv) + sizeof(*tent);
+
+ memcpy(ctlv + 1, tent, sizeof(*tent));
+ tent = (ipfw_obj_tentry *)(ctlv + 1);
if (update != 0)
tent->head.flags |= IPFW_TF_UPDATE;
tent->head.length = sizeof(ipfw_obj_tentry);
@@ -501,6 +506,19 @@ table_modify_record(ipfw_obj_header *oh, int ac, char *av[], int add, int update
tent.idx = 1;
tentry_fill_key(oh, &tent, *av, &type, &vtype, &xi);
+
+ /*
+ * compability layer: auto-create table if not exists
+ */
+ if (xi.tablename[0] == '\0') {
+ xi.type = type;
+ xi.vtype = vtype;
+ strlcpy(xi.tablename, oh->ntlv.name, sizeof(xi.tablename));
+ fprintf(stderr, "DEPRECATED: inserting data info non-existent "
+ "table %s. (auto-created)\n", xi.tablename);
+ table_do_create(oh, &xi);
+ }
+
oh->ntlv.type = type;
ac--; av++;
@@ -659,6 +677,7 @@ tentry_fill_key(ipfw_obj_header *oh, ipfw_obj_tentry *tent, char *key,
{
uint8_t type, vtype;
int error;
+ char *del;
type = 0;
vtype = 0;
@@ -678,6 +697,8 @@ tentry_fill_key(ipfw_obj_header *oh, ipfw_obj_tentry *tent, char *key,
* Compability layer: try to interpret data as CIDR
* before failing.
*/
+ if ((del = strchr(key, '/')) != NULL)
+ *del = '\0';
if (inet_pton(AF_INET, key, &tent->k.addr6) == 1 ||
inet_pton(AF_INET6, key, &tent->k.addr6) == 1) {
/* OK Prepare and send */
@@ -690,8 +711,10 @@ tentry_fill_key(ipfw_obj_header *oh, ipfw_obj_tentry *tent, char *key,
} else {
/* Inknown key */
errx(EX_USAGE, "Table %s does not exist, cannot guess "
- "key type", oh->ntlv.name);
+ "key '%s' type", oh->ntlv.name, key);
}
+ if (del != NULL)
+ *del = '/';
}
tentry_fill_key_type(key, tent, type);
OpenPOWER on IntegriCloud