Show algorithm-specific data in "table info" output.

This commit is contained in:
Alexander V. Chernikov 2014-08-03 12:19:45 +00:00
parent a399f8be58
commit 5f379342d2
5 changed files with 243 additions and 20 deletions

View File

@ -473,6 +473,58 @@ table_get_info(ipfw_obj_header *oh, ipfw_xtable_info *i)
return (0);
}
static struct _s_x tablealgoclass[] = {
{ "hash", IPFW_TACLASS_HASH },
{ "array", IPFW_TACLASS_ARRAY },
{ "radix", IPFW_TACLASS_RADIX },
{ NULL, 0 }
};
struct ta_cldata {
uint8_t taclass;
uint8_t spare4;
uint16_t itemsize;
uint16_t itemsize6;
uint32_t size;
uint32_t count;
};
/*
* Print global/per-AF table @i algorithm info.
*/
static void
table_show_tainfo(ipfw_xtable_info *i, struct ta_cldata *d,
const char *af, const char *taclass)
{
switch (d->taclass) {
case IPFW_TACLASS_HASH:
case IPFW_TACLASS_ARRAY:
printf(" %salgorithm %s info\n", af, taclass);
if (d->itemsize == d->itemsize6)
printf(" size: %u items: %u itemsize: %u\n",
d->size, d->count, d->itemsize);
else
printf(" size: %u items: %u "
"itemsize4: %u itemsize6: %u\n",
d->size, d->count,
d->itemsize, d->itemsize6);
break;
case IPFW_TACLASS_RADIX:
printf(" %salgorithm %s info\n", af, taclass);
if (d->itemsize == d->itemsize6)
printf(" items: %u itemsize: %u\n",
d->count, d->itemsize);
else
printf(" items: %u "
"itemsize4: %u itemsize6: %u\n",
d->count, d->itemsize, d->itemsize6);
break;
default:
printf(" algo class: %s\n", taclass);
}
}
/*
* Prints table info struct @i in human-readable form.
*/
@ -480,6 +532,9 @@ static int
table_show_info(ipfw_xtable_info *i, void *arg)
{
const char *vtype;
ipfw_ta_tinfo *tainfo;
int afdata, afitem;
struct ta_cldata d;
char ttype[64];
table_print_type(ttype, sizeof(ttype), i->type, i->tflags);
@ -494,6 +549,45 @@ table_show_info(ipfw_xtable_info *i, void *arg)
if (i->limit > 0)
printf(" limit: %u\n", i->limit);
/* Print algo-specific info if any */
if ((i->ta_info.flags & IPFW_TATFLAGS_DATA) == 0)
return (0);
tainfo = &i->ta_info;
afdata = 0;
afitem = 0;
if (tainfo->flags & IPFW_TATFLAGS_AFDATA)
afdata = 1;
if (tainfo->flags & IPFW_TATFLAGS_AFITEM)
afitem = 1;
memset(&d, 0, sizeof(d));
d.taclass = tainfo->taclass4;
d.size = tainfo->size4;
d.count = tainfo->count4;
d.itemsize = tainfo->itemsize4;
if (afdata == 0 && afitem != 0)
d.itemsize6 = tainfo->itemsize6;
else
d.itemsize6 = d.itemsize;
if ((vtype = match_value(tablealgoclass, d.taclass)) == NULL)
vtype = "unknown";
if (afdata == 0) {
table_show_tainfo(i, &d, "", vtype);
} else {
table_show_tainfo(i, &d, "IPv4 ", vtype);
memset(&d, 0, sizeof(d));
d.taclass = tainfo->taclass6;
if ((vtype = match_value(tablealgoclass, d.taclass)) == NULL)
vtype = "unknown";
d.size = tainfo->size6;
d.count = tainfo->count6;
d.itemsize = tainfo->itemsize6;
d.itemsize6 = d.itemsize;
table_show_tainfo(i, &d, "IPv6 ", vtype);
}
return (0);
}

View File

@ -798,24 +798,27 @@ typedef struct _ipfw_obj_ctlv {
uint8_t spare;
} ipfw_obj_ctlv;
typedef struct _ifpw_ta_tinfo {
typedef struct _ipfw_ta_tinfo {
uint32_t flags; /* Format flags */
uint8_t taclass; /* algorithm class */
uint8_t spare0;
uint16_t spare1;
uint32_t rssize4; /* runtime structure size */
uint32_t rcount4; /* number of items in runtime */
uint32_t rsize4; /* item size in runtime */
uint32_t rssize6; /* runtime structure size */
uint32_t rcount6; /* number of items in runtime */
uint32_t rsize6; /* item size in runtime */
} ifpw_ta_tinfo;
uint32_t spare;
uint8_t taclass4; /* algorithm class */
uint8_t spare4;
uint16_t itemsize4; /* item size in runtime */
uint32_t size4; /* runtime structure size */
uint32_t count4; /* number of items in runtime */
uint8_t taclass6; /* algorithm class */
uint8_t spare6;
uint16_t itemsize6; /* item size in runtime */
uint32_t size6; /* runtime structure size */
uint32_t count6; /* number of items in runtime */
} ipfw_ta_tinfo;
#define IPFW_TACLASS_HASH 1 /* algo is based on hash */
#define IPFW_TACLASS_ARRAY 2 /* algo is based on array */
#define IPFW_TACLASS_RADIX 3 /* algo is based on radix tree */
#define IPFW_TATFLAGS_DATA 0x0001 /* Has data filled in */
#define IPFW_TATFLAGS_AF 0x0002 /* Separate data per AF */
#define IPFW_TATFLAGS_AFDATA 0x0002 /* Separate data per AF */
#define IPFW_TATFLAGS_AFITEM 0x0004 /* diff. items per AF */
typedef struct _ipfw_xtable_info {
uint8_t type; /* table type (cidr,iface,..) */
@ -831,7 +834,7 @@ typedef struct _ipfw_xtable_info {
uint32_t spare;
char tablename[64]; /* table name */
char algoname[64]; /* algorithm name */
ifpw_ta_tinfo ta_info; /* additional algo stats */
ipfw_ta_tinfo ta_info; /* additional algo stats */
} ipfw_xtable_info;
#define IPFW_TFFLAG_SRCIP 0x01
#define IPFW_TFFLAG_DSTIP 0x02

View File

@ -1341,6 +1341,7 @@ export_table_info(struct ip_fw_chain *ch, struct table_config *tc,
ipfw_xtable_info *i)
{
struct table_info *ti;
struct table_algo *ta;
i->type = tc->no.type;
i->tflags = tc->tflags;
@ -1353,13 +1354,19 @@ export_table_info(struct ip_fw_chain *ch, struct table_config *tc,
i->size = tc->count * sizeof(ipfw_obj_tentry);
i->size += sizeof(ipfw_obj_header) + sizeof(ipfw_xtable_info);
strlcpy(i->tablename, tc->tablename, sizeof(i->tablename));
if (tc->ta->print_config != NULL) {
ti = KIDX_TO_TI(ch, tc->no.kidx);
ta = tc->ta;
if (ta->print_config != NULL) {
/* Use algo function to print table config to string */
ti = KIDX_TO_TI(ch, tc->no.kidx);
tc->ta->print_config(tc->astate, ti, i->algoname,
ta->print_config(tc->astate, ti, i->algoname,
sizeof(i->algoname));
} else
strlcpy(i->algoname, tc->ta->name, sizeof(i->algoname));
strlcpy(i->algoname, ta->name, sizeof(i->algoname));
/* Dump algo-specific data, if possible */
if (ta->dump_tinfo != NULL) {
ta->dump_tinfo(tc->astate, ti, &i->ta_info);
i->ta_info.flags |= IPFW_TATFLAGS_DATA;
}
}
struct dump_table_args {

View File

@ -97,8 +97,8 @@ typedef int ta_dump_tentry(void *ta_state, struct table_info *ti, void *e,
ipfw_obj_tentry *tent);
typedef int ta_find_tentry(void *ta_state, struct table_info *ti,
ipfw_obj_tentry *tent);
typedef int ta_dump_tinfo(void *ta_state, struct table_info *ti,
ifpw_ta_tinfo *tinfo);
typedef void ta_dump_tinfo(void *ta_state, struct table_info *ti,
ipfw_ta_tinfo *tinfo);
struct table_algo {
char name[16];

View File

@ -120,6 +120,13 @@ struct radix_cidr_xentry {
uint8_t masklen;
};
struct radix_cfg {
struct radix_node_head *head4;
struct radix_node_head *head6;
size_t count4;
size_t count6;
};
struct ta_buf_cidr
{
void *ent_ptr;
@ -177,6 +184,7 @@ static int
ta_init_radix(struct ip_fw_chain *ch, void **ta_state, struct table_info *ti,
char *data, uint8_t tflags)
{
struct radix_cfg *cfg;
if (!rn_inithead(&ti->state, OFF_LEN_INET))
return (ENOMEM);
@ -185,7 +193,9 @@ ta_init_radix(struct ip_fw_chain *ch, void **ta_state, struct table_info *ti,
return (ENOMEM);
}
*ta_state = NULL;
cfg = malloc(sizeof(struct radix_cfg), M_IPFW, M_WAITOK | M_ZERO);
*ta_state = cfg;
ti->lookup = ta_lookup_radix;
return (0);
@ -207,8 +217,11 @@ flush_radix_entry(struct radix_node *rn, void *arg)
static void
ta_destroy_radix(void *ta_state, struct table_info *ti)
{
struct radix_cfg *cfg;
struct radix_node_head *rnh;
cfg = (struct radix_cfg *)ta_state;
rnh = (struct radix_node_head *)(ti->state);
rnh->rnh_walktree(rnh, flush_radix_entry, rnh);
rn_detachhead(&ti->state);
@ -216,6 +229,27 @@ ta_destroy_radix(void *ta_state, struct table_info *ti)
rnh = (struct radix_node_head *)(ti->xstate);
rnh->rnh_walktree(rnh, flush_radix_entry, rnh);
rn_detachhead(&ti->xstate);
free(cfg, M_IPFW);
}
/*
* Provide algo-specific table info
*/
static void
ta_dump_radix_tinfo(void *ta_state, struct table_info *ti, ipfw_ta_tinfo *tinfo)
{
struct radix_cfg *cfg;
cfg = (struct radix_cfg *)ta_state;
tinfo->flags = IPFW_TATFLAGS_AFDATA | IPFW_TATFLAGS_AFITEM;
tinfo->taclass4 = IPFW_TACLASS_RADIX;
tinfo->count4 = cfg->count4;
tinfo->itemsize4 = sizeof(struct radix_cidr_entry);
tinfo->taclass6 = IPFW_TACLASS_RADIX;
tinfo->count6 = cfg->count6;
tinfo->itemsize6 = sizeof(struct radix_cidr_xentry);
}
static int
@ -408,11 +442,13 @@ static int
ta_add_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
void *ta_buf, uint32_t *pnum)
{
struct radix_cfg *cfg;
struct radix_node_head *rnh;
struct radix_node *rn;
struct ta_buf_cidr *tb;
uint32_t *old_value, value;
cfg = (struct radix_cfg *)ta_state;
tb = (struct ta_buf_cidr *)ta_buf;
if (tei->subtype == AF_INET)
@ -451,6 +487,10 @@ ta_add_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
return (EINVAL);
}
if (tei->subtype == AF_INET)
cfg->count4++;
else
cfg->count6++;
tb->ent_ptr = NULL;
*pnum = 1;
@ -499,10 +539,12 @@ static int
ta_del_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
void *ta_buf, uint32_t *pnum)
{
struct radix_cfg *cfg;
struct radix_node_head *rnh;
struct radix_node *rn;
struct ta_buf_cidr *tb;
cfg = (struct radix_cfg *)ta_state;
tb = (struct ta_buf_cidr *)ta_buf;
if (tei->subtype == AF_INET)
@ -523,6 +565,10 @@ ta_del_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
if (rn == NULL)
return (ENOENT);
if (tei->subtype == AF_INET)
cfg->count4--;
else
cfg->count6--;
*pnum = 1;
return (0);
@ -569,6 +615,7 @@ struct table_algo cidr_radix = {
.foreach = ta_foreach_radix,
.dump_tentry = ta_dump_radix_tentry,
.find_tentry = ta_find_radix_tentry,
.dump_tinfo = ta_dump_radix_tinfo,
.has_space = ta_has_space_radix,
};
@ -962,6 +1009,24 @@ ta_destroy_chash(void *ta_state, struct table_info *ti)
free(cfg, M_IPFW);
}
static void
ta_dump_chash_tinfo(void *ta_state, struct table_info *ti, ipfw_ta_tinfo *tinfo)
{
struct chash_cfg *cfg;
cfg = (struct chash_cfg *)ta_state;
tinfo->flags = IPFW_TATFLAGS_AFDATA | IPFW_TATFLAGS_AFITEM;
tinfo->taclass4 = IPFW_TACLASS_HASH;
tinfo->size4 = cfg->size4;
tinfo->count4 = cfg->items4;
tinfo->itemsize4 = sizeof(struct chashentry);
tinfo->taclass6 = IPFW_TACLASS_HASH;
tinfo->size6 = cfg->size6;
tinfo->count6 = cfg->items6;
tinfo->itemsize6 = sizeof(struct chashentry);
}
static int
ta_dump_chash_tentry(void *ta_state, struct table_info *ti, void *e,
ipfw_obj_tentry *tent)
@ -1464,6 +1529,7 @@ struct table_algo cidr_hash = {
.dump_tentry = ta_dump_chash_tentry,
.find_tentry = ta_find_chash_tentry,
.print_config = ta_print_chash_config,
.dump_tinfo = ta_dump_chash_tinfo,
.has_space = ta_has_space_chash,
.prepare_mod = ta_prepare_mod_chash,
.fill_mod = ta_fill_mod_chash,
@ -1714,6 +1780,22 @@ ta_destroy_ifidx(void *ta_state, struct table_info *ti)
free(icfg, M_IPFW);
}
/*
* Provide algo-specific table info
*/
static void
ta_dump_ifidx_tinfo(void *ta_state, struct table_info *ti, ipfw_ta_tinfo *tinfo)
{
struct iftable_cfg *cfg;
cfg = (struct iftable_cfg *)ta_state;
tinfo->taclass4 = IPFW_TACLASS_ARRAY;
tinfo->size4 = cfg->size;
tinfo->count4 = cfg->used;
tinfo->itemsize4 = sizeof(struct ifidx);
}
/*
* Prepare state to add to the table:
* allocate ifentry and reference needed interface.
@ -2137,6 +2219,7 @@ struct table_algo iface_idx = {
.foreach = ta_foreach_ifidx,
.dump_tentry = ta_dump_ifidx_tentry,
.find_tentry = ta_find_ifidx_tentry,
.dump_tinfo = ta_dump_ifidx_tinfo,
.has_space = ta_has_space_ifidx,
.prepare_mod = ta_prepare_mod_ifidx,
.fill_mod = ta_fill_mod_ifidx,
@ -2254,6 +2337,22 @@ ta_destroy_numarray(void *ta_state, struct table_info *ti)
free(cfg, M_IPFW);
}
/*
* Provide algo-specific table info
*/
static void
ta_dump_numarray_tinfo(void *ta_state, struct table_info *ti, ipfw_ta_tinfo *tinfo)
{
struct numarray_cfg *cfg;
cfg = (struct numarray_cfg *)ta_state;
tinfo->taclass4 = IPFW_TACLASS_ARRAY;
tinfo->size4 = cfg->size;
tinfo->count4 = cfg->used;
tinfo->itemsize4 = sizeof(struct numarray);
}
/*
* Prepare for addition/deletion to an array.
*/
@ -2522,6 +2621,7 @@ struct table_algo number_array = {
.foreach = ta_foreach_numarray,
.dump_tentry = ta_dump_numarray_tentry,
.find_tentry = ta_find_numarray_tentry,
.dump_tinfo = ta_dump_numarray_tinfo,
.has_space = ta_has_space_numarray,
.prepare_mod = ta_prepare_mod_numarray,
.fill_mod = ta_fill_mod_numarray,
@ -2778,6 +2878,24 @@ ta_destroy_fhash(void *ta_state, struct table_info *ti)
free(cfg, M_IPFW);
}
/*
* Provide algo-specific table info
*/
static void
ta_dump_fhash_tinfo(void *ta_state, struct table_info *ti, ipfw_ta_tinfo *tinfo)
{
struct fhash_cfg *cfg;
cfg = (struct fhash_cfg *)ta_state;
tinfo->flags = IPFW_TATFLAGS_AFITEM;
tinfo->taclass4 = IPFW_TACLASS_HASH;
tinfo->size4 = cfg->size;
tinfo->count4 = cfg->items;
tinfo->itemsize4 = sizeof(struct fhashentry4);
tinfo->itemsize6 = sizeof(struct fhashentry6);
}
static int
ta_dump_fhash_tentry(void *ta_state, struct table_info *ti, void *e,
ipfw_obj_tentry *tent)
@ -3190,6 +3308,7 @@ struct table_algo flow_hash = {
.foreach = ta_foreach_fhash,
.dump_tentry = ta_dump_fhash_tentry,
.find_tentry = ta_find_fhash_tentry,
.dump_tinfo = ta_dump_fhash_tinfo,
.has_space = ta_has_space_fhash,
.prepare_mod = ta_prepare_mod_fhash,
.fill_mod = ta_fill_mod_fhash,