diff options
author | melifaro <melifaro@FreeBSD.org> | 2014-07-26 13:37:25 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2014-07-26 13:37:25 +0000 |
commit | 505e5ae08158dae524fad92308b69c209a5f69d9 (patch) | |
tree | 992bd8b8c50d4af7fe911750b6c929b8a8fe07c6 /sbin/ipfw/tables.c | |
parent | deb9ca0f18daa165fa9fe29716230066af8c4707 (diff) | |
download | FreeBSD-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.c | 31 |
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); |