svn commit: r269276 - in projects/ipfw: sbin/ipfw sys/netinet sys/netpfil/ipfw
Alexander V. Chernikov
melifaro at FreeBSD.org
Tue Jul 29 22:44:28 UTC 2014
Author: melifaro
Date: Tue Jul 29 22:44:26 2014
New Revision: 269276
URL: http://svnweb.freebsd.org/changeset/base/269276
Log:
* Dump available table algorithms via "ipfw talist" cmd.
Kernel changes:
* Add type/refcount fields to table algo instances.
* Add IP_FW_TABLES_ALIST opcode to export available algorihms to userland.
Userland changes:
* Fix cores on empty input inside "ipfw table" handler.
* Add "ipfw talist" cmd to print availabled kernel algorithms.
* Change "table info" output to reflect long algorithm config lines.
Modified:
projects/ipfw/sbin/ipfw/ipfw2.h
projects/ipfw/sbin/ipfw/main.c
projects/ipfw/sbin/ipfw/tables.c
projects/ipfw/sys/netinet/ip_fw.h
projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c
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/ipfw2.h
==============================================================================
--- projects/ipfw/sbin/ipfw/ipfw2.h Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sbin/ipfw/ipfw2.h Tue Jul 29 22:44:26 2014 (r269276)
@@ -297,6 +297,7 @@ void ipfw_flush(int force);
void ipfw_zero(int ac, char *av[], int optname);
void ipfw_list(int ac, char *av[], int show_counters);
void ipfw_list_tifaces(void);
+void ipfw_list_ta(int ac, char *av[]);
#ifdef PF
/* altq.c */
Modified: projects/ipfw/sbin/ipfw/main.c
==============================================================================
--- projects/ipfw/sbin/ipfw/main.c Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sbin/ipfw/main.c Tue Jul 29 22:44:26 2014 (r269276)
@@ -440,6 +440,8 @@ ipfw_main(int oldac, char **oldav)
ipfw_table_handler(ac, av);
else if (_substrcmp(*av, "iflist") == 0)
ipfw_list_tifaces();
+ else if (_substrcmp(*av, "talist") == 0)
+ ipfw_list_ta(ac, av);
else
errx(EX_USAGE, "bad command `%s'", *av);
}
Modified: projects/ipfw/sbin/ipfw/tables.c
==============================================================================
--- projects/ipfw/sbin/ipfw/tables.c Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sbin/ipfw/tables.c Tue Jul 29 22:44:26 2014 (r269276)
@@ -146,6 +146,7 @@ ipfw_table_handler(int ac, char *av[])
set = 0;
ac--; av++;
+ NEED1("table needs name");
tablename = *av;
if (table_check_name(tablename) == 0) {
@@ -158,11 +159,11 @@ ipfw_table_handler(int ac, char *av[])
errx(EX_USAGE, "table name %s is invalid", tablename);
}
ac--; av++;
+ NEED1("table needs command");
if ((tcmd = match_token(tablecmds, *av)) == -1)
errx(EX_USAGE, "invalid table command %s", *av);
- NEED1("table needs command");
switch (tcmd) {
case TOK_LIST:
case TOK_INFO:
@@ -416,8 +417,8 @@ table_show_info(ipfw_xtable_info *i, voi
vtype = "unknown";
printf(" type: %s, kindex: %d\n", ttype, i->kidx);
- printf(" valtype: %s, algorithm: %s\n", vtype, i->algoname);
- printf(" references: %u\n", i->refcnt);
+ 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);
return (0);
@@ -901,6 +902,59 @@ table_show_entry(ipfw_xtable_info *i, ip
}
}
+static int
+table_do_get_algolist(ipfw_obj_lheader **polh)
+{
+ ipfw_obj_lheader req, *olh;
+ size_t sz;
+ int error;
+
+ memset(&req, 0, sizeof(req));
+ sz = sizeof(req);
+
+ error = do_get3(IP_FW_TABLES_ALIST, &req.opheader, &sz);
+ if (error != 0 && error != ENOMEM)
+ return (error);
+
+ sz = req.size;
+ if ((olh = calloc(1, sz)) == NULL)
+ return (ENOMEM);
+
+ olh->size = sz;
+ if ((error = do_get3(IP_FW_TABLES_ALIST, &olh->opheader, &sz)) != 0) {
+ free(olh);
+ return (error);
+ }
+
+ *polh = olh;
+ return (0);
+}
+
+void
+ipfw_list_ta(int ac, char *av[])
+{
+ ipfw_obj_lheader *olh;
+ ipfw_ta_info *info;
+ int error, i;
+ const char *atype;
+
+ error = table_do_get_algolist(&olh);
+ if (error != 0)
+ err(EX_OSERR, "Unable to request algorithm list");
+
+ info = (ipfw_ta_info *)(olh + 1);
+ for (i = 0; i < olh->count; i++) {
+ if ((atype = match_value(tabletypes, info->type)) == NULL)
+ atype = "unknown";
+
+ printf("%s type: %s references: %u\n", info->algoname,
+ atype, info->refcnt);
+ info = (ipfw_ta_info *)((caddr_t)info + olh->objsize);
+ }
+
+ free(olh);
+}
+
int
compare_ntlv(const void *_a, const void *_b)
{
Modified: projects/ipfw/sys/netinet/ip_fw.h
==============================================================================
--- projects/ipfw/sys/netinet/ip_fw.h Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sys/netinet/ip_fw.h Tue Jul 29 22:44:26 2014 (r269276)
@@ -89,6 +89,7 @@ typedef struct _ip_fw3_opheader {
#define IP_FW_XADD 98 /* add entry */
#define IP_FW_TABLE_XFIND 99 /* finds an entry */
#define IP_FW_XIFLIST 100 /* list tracked interfaces */
+#define IP_FW_TABLES_ALIST 101 /* list table algorithms */
/*
* Usage guidelines:
@@ -799,6 +800,15 @@ typedef struct _ipfw_iface_info {
} ipfw_iface_info;
#define IPFW_IFFLAG_RESOLVED 0x01 /* Interface exists */
+typedef struct _ipfw_ta_info {
+ char algoname[32]; /* algorithm name */
+ uint32_t type; /* lookup type */
+ uint32_t flags;
+ uint32_t refcnt;
+ uint32_t spare0;
+ uint64_t spare1;
+} ipfw_ta_info;
+
#define IPFW_OBJTYPE_TABLE 1
typedef struct _ipfw_obj_header {
ip_fw3_opheader opheader; /* IP_FW3 opcode */
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c Tue Jul 29 22:44:26 2014 (r269276)
@@ -2001,6 +2001,9 @@ ipfw_ctl(struct sockopt *sopt)
case IP_FW_TABLE_XFIND: /* IP_FW3 */
error = ipfw_find_table_entry(chain, op3, &sdata);
break;
+ case IP_FW_TABLES_ALIST: /* IP_FW3 */
+ error = ipfw_list_table_algo(chain, &sdata);
+ break;
/*--- LEGACY API ---*/
case IP_FW_TABLE_ADD:
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c Tue Jul 29 22:44:26 2014 (r269276)
@@ -1641,6 +1641,59 @@ ipfw_del_table_algo(struct ip_fw_chain *
free(ta, M_IPFW);
}
+/*
+ * Lists all table algorithms currently available.
+ * Data layout (v0)(current):
+ * Request: [ ipfw_obj_lheader ], size = ipfw_obj_lheader.size
+ * Reply: [ ipfw_obj_lheader ipfw_ta_info x N ]
+ *
+ * Returns 0 on success
+ */
+int
+ipfw_list_table_algo(struct ip_fw_chain *ch, struct sockopt_data *sd)
+{
+ struct _ipfw_obj_lheader *olh;
+ struct tables_config *tcfg;
+ ipfw_ta_info *i;
+ struct table_algo *ta;
+ uint32_t count, n, size;
+
+ olh = (struct _ipfw_obj_lheader *)ipfw_get_sopt_header(sd,sizeof(*olh));
+ if (olh == NULL)
+ return (EINVAL);
+ if (sd->valsize < olh->size)
+ return (EINVAL);
+
+ IPFW_UH_RLOCK(ch);
+ tcfg = CHAIN_TO_TCFG(ch);
+ count = tcfg->algo_count;
+ size = count * sizeof(ipfw_ta_info) + sizeof(ipfw_obj_lheader);
+
+ /* Fill in header regadless of buffer size */
+ olh->count = count;
+ olh->objsize = sizeof(ipfw_ta_info);
+
+ if (size > olh->size) {
+ olh->size = size;
+ IPFW_UH_RUNLOCK(ch);
+ return (ENOMEM);
+ }
+ olh->size = size;
+
+ for (n = 1; n <= count; n++) {
+ i = (ipfw_ta_info *)ipfw_get_sopt_space(sd, sizeof(*i));
+ KASSERT(i != 0, ("previously checked buffer is not enough"));
+ ta = tcfg->algo[n];
+ strlcpy(i->algoname, ta->name, sizeof(i->algoname));
+ i->type = ta->type;
+ i->refcnt = ta->refcnt;
+ }
+
+ IPFW_UH_RUNLOCK(ch);
+
+ return (0);
+}
+
/*
* Tables rewriting code
@@ -1925,6 +1978,7 @@ link_table(struct ip_fw_chain *ch, struc
tc->ta->change_ti(tc->astate, ti);
tc->linked = 1;
+ tc->ta->refcnt++;
}
/*
@@ -1949,6 +2003,7 @@ unlink_table(struct ip_fw_chain *ch, str
ti = KIDX_TO_TI(ch, kidx);
memset(ti, 0, sizeof(struct table_info));
tc->linked = 0;
+ tc->ta->refcnt--;
/* Notify algo on real @ti address */
if (tc->ta->change_ti != NULL)
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h Tue Jul 29 22:44:26 2014 (r269276)
@@ -98,6 +98,9 @@ typedef int ta_find_tentry(void *ta_stat
struct table_algo {
char name[16];
int idx;
+ int type;
+ int refcnt;
+ int spare;
ta_init *init;
ta_destroy *destroy;
ta_prepare_add *prepare_add;
@@ -140,6 +143,7 @@ int ipfw_manage_table_ent(struct ip_fw_c
struct sockopt_data *sd);
int ipfw_flush_table(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
struct sockopt_data *sd);
+int ipfw_list_table_algo(struct ip_fw_chain *ch, struct sockopt_data *sd);
/* Exported to support legacy opcodes */
int add_table_entry(struct ip_fw_chain *ch, struct tid_info *ti,
struct tentry_info *tei);
Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c Tue Jul 29 22:29:32 2014 (r269275)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c Tue Jul 29 22:44:26 2014 (r269276)
@@ -516,6 +516,7 @@ ta_flush_cidr_entry(struct ip_fw_chain *
struct table_algo cidr_radix = {
.name = "cidr:radix",
+ .type = IPFW_TABLE_CIDR,
.init = ta_init_radix,
.destroy = ta_destroy_radix,
.prepare_add = ta_prepare_add_cidr,
@@ -1194,6 +1195,7 @@ ta_flush_chash_entry(struct ip_fw_chain
struct table_algo cidr_hash = {
.name = "cidr:hash",
+ .type = IPFW_TABLE_CIDR,
.init = ta_init_chash,
.destroy = ta_destroy_chash,
.prepare_add = ta_prepare_add_chash,
@@ -1846,6 +1848,7 @@ ta_foreach_ifidx(void *ta_state, struct
struct table_algo iface_idx = {
.name = "iface:array",
+ .type = IPFW_TABLE_INTERFACE,
.init = ta_init_ifidx,
.destroy = ta_destroy_ifidx,
.prepare_add = ta_prepare_add_ifidx,
More information about the svn-src-projects
mailing list