Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Aug 2014 12:19:45 +0000 (UTC)
From:      Alexander V. Chernikov <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r269473 - in projects/ipfw: sbin/ipfw sys/netinet sys/netpfil/ipfw
Message-ID:  <53de28e1.5e71.4156f924@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sun Aug  3 12:19:45 2014
New Revision: 269473
URL: http://svnweb.freebsd.org/changeset/base/269473

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

Modified:
  projects/ipfw/sbin/ipfw/tables.c
  projects/ipfw/sys/netinet/ip_fw.h
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c

Modified: projects/ipfw/sbin/ipfw/tables.c
==============================================================================
--- projects/ipfw/sbin/ipfw/tables.c	Sun Aug  3 11:43:14 2014	(r269472)
+++ projects/ipfw/sbin/ipfw/tables.c	Sun Aug  3 12:19:45 2014	(r269473)
@@ -473,6 +473,58 @@ table_get_info(ipfw_obj_header *oh, ipfw
 	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, voi
 	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);
 }
 

Modified: projects/ipfw/sys/netinet/ip_fw.h
==============================================================================
--- projects/ipfw/sys/netinet/ip_fw.h	Sun Aug  3 11:43:14 2014	(r269472)
+++ projects/ipfw/sys/netinet/ip_fw.h	Sun Aug  3 12:19:45 2014	(r269473)
@@ -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

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Sun Aug  3 11:43:14 2014	(r269472)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Sun Aug  3 12:19:45 2014	(r269473)
@@ -1341,6 +1341,7 @@ export_table_info(struct ip_fw_chain *ch
     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
 	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 {

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h	Sun Aug  3 11:43:14 2014	(r269472)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h	Sun Aug  3 12:19:45 2014	(r269473)
@@ -97,8 +97,8 @@ typedef int ta_dump_tentry(void *ta_stat
     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];

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Sun Aug  3 11:43:14 2014	(r269472)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Sun Aug  3 12:19:45 2014	(r269473)
@@ -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, vo
 		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,
 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 
 	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 tabl
 		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 tabl
 	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 
 	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,
@@ -1715,6 +1781,22 @@ ta_destroy_ifidx(void *ta_state, struct 
 }
 
 /*
+ * 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,
@@ -2255,6 +2338,22 @@ ta_destroy_numarray(void *ta_state, stru
 }
 
 /*
+ * 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.
  */
 static int
@@ -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 
 	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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53de28e1.5e71.4156f924>