diff options
author | melifaro <melifaro@FreeBSD.org> | 2014-08-01 15:17:46 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2014-08-01 15:17:46 +0000 |
commit | 178311d9d4c0a512292c01d751831b7155819d27 (patch) | |
tree | 1039246d324a5e4fb33337aa1b6f3cc96b2763d2 /sbin/ipfw/tables.c | |
parent | 6d7452f13b0a8fdccc3fb65e9e726d366c6c71b0 (diff) | |
download | FreeBSD-src-178311d9d4c0a512292c01d751831b7155819d27.zip FreeBSD-src-178311d9d4c0a512292c01d751831b7155819d27.tar.gz |
* Permit limiting number of items in table.
Kernel changes:
* Add TEI_FLAGS_DONTADD entry flag to indicate that insert is not possible
* Support given flag in all algorithms
* Add "limit" field to ipfw_xtable_info
* Add actual limiting code into add_table_entry()
Userland changes:
* Add "limit" option as "create" table sub-option. Limit modification
is currently impossible.
* Print human-readable errors in table enry addition/deletion code.
Diffstat (limited to 'sbin/ipfw/tables.c')
-rw-r--r-- | sbin/ipfw/tables.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c index f94ca72..e36def6 100644 --- a/sbin/ipfw/tables.c +++ b/sbin/ipfw/tables.c @@ -251,9 +251,10 @@ table_fill_objheader(ipfw_obj_header *oh, ipfw_xtable_info *i) } static struct _s_x tablenewcmds[] = { - { "type", TOK_TYPE}, + { "type", TOK_TYPE }, { "valtype", TOK_VALTYPE }, { "algo", TOK_ALGO }, + { "limit", TOK_LIMIT }, { NULL, 0 } }; @@ -341,6 +342,11 @@ table_create(ipfw_obj_header *oh, int ac, char *av[]) ac--; av++; switch (tcmd) { + case TOK_LIMIT: + NEED1("limit value required"); + xi.limit = strtol(*av, NULL, 10); + ac--; av++; + break; case TOK_TYPE: NEED1("table type required"); /* Type may have suboptions after ':' */ @@ -485,6 +491,8 @@ table_show_info(ipfw_xtable_info *i, void *arg) printf(" valtype: %s, references: %u\n", vtype, i->refcnt); printf(" algorithm: %s\n", i->algoname); printf(" items: %u, size: %u\n", i->count, i->size); + if (i->limit > 0) + printf(" limit: %u\n", i->limit); return (0); } @@ -561,8 +569,8 @@ table_modify_record(ipfw_obj_header *oh, int ac, char *av[], int add, int update ipfw_obj_tentry tent; ipfw_xtable_info xi; uint8_t type, vtype; - int cmd; - char *texterr; + int cmd, error; + char *texterr, *etxt; if (ac == 0) errx(EX_USAGE, "address required"); @@ -592,14 +600,34 @@ table_modify_record(ipfw_obj_header *oh, int ac, char *av[], int add, int update if (ac > 0) tentry_fill_value(oh, &tent, *av, type, vtype); cmd = IP_FW_TABLE_XADD; - texterr = "setsockopt(IP_FW_TABLE_XADD)"; + texterr = "Adding record failed"; } else { cmd = IP_FW_TABLE_XDEL; - texterr = "setsockopt(IP_FW_TABLE_XDEL)"; + texterr = "Deleting record failed"; + } + + if ((error = table_do_modify_record(cmd, oh, &tent, update)) == 0) + return; + + /* Try to provide more human-readable error */ + switch (error) { + case EEXIST: + etxt = "record already exists"; + break; + case EFBIG: + etxt = "limit hit"; + break; + case ESRCH: + etxt = "table not found"; + break; + case ENOENT: + etxt = "record not found"; + break; + default: + etxt = strerror(error); } - if (table_do_modify_record(cmd, oh, &tent, update) != 0) - err(EX_OSERR, "%s", texterr); + errx(EX_OSERR, "%s: %s", texterr, etxt); } static int |