Kernel changes:

* Fix buffer calculation for table dumps
* Fix IPv6 radix entiries addition broken in r269371.

Userland changes:
* Fix bug in retrieving statric ruleset
* Fix several bugs in retrieving table list
This commit is contained in:
Alexander V. Chernikov 2014-08-08 21:09:22 +00:00
parent 8bd1921248
commit 720ee730c6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/ipfw/; revision=269739
4 changed files with 33 additions and 24 deletions

View File

@ -2659,7 +2659,7 @@ ipfw_get_config(struct cmdline_opts *co, struct format_opts *fo,
sz = 4096;
cfg = NULL;
for (i = 0; i < 10; i++) {
for (i = 0; i < 16; i++) {
if (cfg != NULL)
free(cfg);
if ((cfg = calloc(1, sz)) == NULL)
@ -2676,9 +2676,10 @@ ipfw_get_config(struct cmdline_opts *co, struct format_opts *fo,
}
/* Buffer size is not enough. Try to increase */
sz = sz * 2 + 200;
sz = sz * 2;
if (sz < cfg->size)
sz = cfg->size + 200;
sz = cfg->size;
continue;
}
*pcfg = cfg;

View File

@ -67,7 +67,7 @@ static void table_fill_ntlv(ipfw_obj_ntlv *ntlv, char *name, uint32_t set,
static int table_flush_one(ipfw_xtable_info *i, void *arg);
static int table_show_one(ipfw_xtable_info *i, void *arg);
static int table_get_list(ipfw_xtable_info *i, ipfw_obj_header *oh);
static int table_do_get_list(ipfw_xtable_info *i, ipfw_obj_header **poh);
static void table_show_list(ipfw_obj_header *oh, int need_header);
static void table_show_entry(ipfw_xtable_info *i, ipfw_obj_tentry *tent);
@ -760,10 +760,7 @@ table_show_one(ipfw_xtable_info *i, void *arg)
ipfw_obj_header *oh;
int error;
if ((oh = calloc(1, i->size)) == NULL)
return (ENOMEM);
if ((error = table_get_list(i, oh)) != 0) {
if ((error = table_do_get_list(i, &oh)) != 0) {
err(EX_OSERR, "Error requesting table %s list", i->tablename);
return (error);
}
@ -1304,31 +1301,43 @@ tables_foreach(table_cb_t *f, void *arg, int sort)
/*
* Retrieves all entries for given table @i in
* eXtended format. Assumes buffer of size
* @i->size has already been allocated by caller.
* eXtended format. Allocate buffer large enough
* to store result. Called needs to free it later.
*
* Returns 0 on success.
*/
static int
table_get_list(ipfw_xtable_info *i, ipfw_obj_header *oh)
table_do_get_list(ipfw_xtable_info *i, ipfw_obj_header **poh)
{
ipfw_obj_header *oh;
size_t sz;
int error, c;
sz = 0;
for (c = 0; c < 3; c++) {
table_fill_objheader(oh, i);
oh = NULL;
error = 0;
for (c = 0; c < 8; c++) {
if (sz < i->size)
sz = i->size;
sz = i->size + 44;
if (oh != NULL)
free(oh);
if ((oh = calloc(1, sz)) == NULL)
continue;
table_fill_objheader(oh, i);
oh->opheader.version = 1; /* Current version */
error = do_get3(IP_FW_TABLE_XLIST, &oh->opheader, &sz);
if (error != ENOMEM)
return (errno);
}
if (error == 0) {
*poh = oh;
return (0);
}
return (ENOMEM);
if (error != ENOMEM)
break;
}
free(oh);
return (error);
}
/*

View File

@ -1245,9 +1245,8 @@ ipfw_dump_table_v1(struct ip_fw_chain *ch, struct sockopt_data *sd)
return (ESRCH);
}
export_table_info(ch, tc, i);
sz = tc->count;
if (sd->valsize < sz + tc->count * sizeof(ipfw_obj_tentry)) {
if (sd->valsize < i->size) {
/*
* Submitted buffer size is not enough.

View File

@ -342,7 +342,7 @@ tei_to_sockaddr_ent(struct tentry_info *tei, struct sockaddr *sa,
{
int mlen;
struct sockaddr_in *addr, *mask;
struct sockaddr_in6 *addr6, *mask6;
struct sa_in6 *addr6, *mask6;
in_addr_t a4;
mlen = tei->masklen;
@ -367,8 +367,8 @@ tei_to_sockaddr_ent(struct tentry_info *tei, struct sockaddr *sa,
#ifdef INET6
} else if (tei->subtype == AF_INET6) {
/* IPv6 case */
addr6 = (struct sockaddr_in6 *)sa;
mask6 = (struct sockaddr_in6 *)ma;
addr6 = (struct sa_in6 *)sa;
mask6 = (struct sa_in6 *)ma;
/* Set 'total' structure length */
KEY_LEN(*addr6) = KEY_LEN_INET6;
KEY_LEN(*mask6) = KEY_LEN_INET6;