Date: Tue, 29 Jul 2014 22:44:26 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r269276 - in projects/ipfw: sbin/ipfw sys/netinet sys/netpfil/ipfw Message-ID: <201407292244.s6TMiR8l010807@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407292244.s6TMiR8l010807>