Show algorithm-specific data in "table info" output.
This commit is contained in:
parent
a399f8be58
commit
5f379342d2
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
/* 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 = tc->ta;
|
||||
if (ta->print_config != NULL) {
|
||||
/* Use algo function to print table config to string */
|
||||
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 {
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user