Date: Mon, 17 Aug 2009 09:19:40 GMT From: Marta Carbone <marta@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 167434 for review Message-ID: <200908170919.n7H9JedE027727@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167434 Change 167434 by marta@marta_onelab1 on 2009/08/17 09:19:25 Split the rules listing in two separated requests. Affected files ... .. //depot/projects/soc2009/marta_ipfw/src/sbin/ipfw/ipfw2.c#3 edit .. //depot/projects/soc2009/marta_ipfw/src/sbin/ipfw/ipfw2.h#3 edit .. //depot/projects/soc2009/marta_ipfw/src/sys/netinet/in.h#2 edit .. //depot/projects/soc2009/marta_ipfw/src/sys/netinet/ipfw/ip_fw2.c#3 edit .. //depot/projects/soc2009/marta_ipfw/src/sys/netinet/raw_ip.c#2 edit Differences ... ==== //depot/projects/soc2009/marta_ipfw/src/sbin/ipfw/ipfw2.c#3 (text+ko) ==== @@ -357,7 +357,8 @@ if (s < 0) err(EX_UNAVAILABLE, "socket"); - if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET || + if (optname == IP_FW_GET || optname == IP_FW_DYN_GET || + optname == IP_DUMMYNET_GET || optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST || optname == IP_FW_TABLE_GETSIZE || optname == IP_FW_NAT_GET_CONFIG || @@ -1727,19 +1728,17 @@ * * In case of success EX_OK is returned. */ +/* decompile static rules */ int -ipfw_list_decompile(void *data, int nbytes, struct sbuf *out, struct cmdline_opts *co) +decompile_static_rules(void *data, int nbytes, struct sbuf *out, struct cmdline_opts *co) { struct ip_fw *r; - ipfw_dyn_rule *dynrules, *d; int exitval = EX_OK; char *lim; int bcwidth, n, pcwidth, width; int nstat; /* number of static rules */ - int ndyn; /* number of dynamic rules */ int seen = 0; /* flag for rules presence */ - uint8_t set; if (co->do_pipe) { ipfw_list_pipes(data, nbytes, out, co); @@ -1756,15 +1755,6 @@ ++nstat, r = NEXT(r) ) ; /* nothing */ - /* - * Count dynamic rules. This is easier as they have - * fixed size. - */ - r = NEXT(r); - dynrules = (ipfw_dyn_rule *)r ; - n = (char *)r - (char *)data; - ndyn = (nbytes - n) / sizeof *dynrules; - /* if showing stats, figure out column widths ahead of time */ bcwidth = pcwidth = 0; if (co->do_acct) { @@ -1786,27 +1776,7 @@ bcwidth = width; } } - if (co->do_dynamic && ndyn) { - for (n = 0, d = dynrules; n < ndyn; n++, d++) { - if (co->use_set) { - /* skip rules from another set */ - bcopy((char *)&d->rule + sizeof(uint16_t), - &set, sizeof(uint8_t)); - if (set != co->use_set - 1) - continue; - } - width = snprintf(NULL, 0, "%llu", - align_uint64(&d->pcnt)); - if (width > pcwidth) - pcwidth = width; - width = snprintf(NULL, 0, "%llu", - align_uint64(&d->bcnt)); - if (width > bcwidth) - bcwidth = width; - } - } - /* show static rules */ for (n = 0, r = data; n < nstat; n++, r = NEXT(r)) { /* skip boundaries */ @@ -1833,30 +1803,75 @@ warnx("rules %lu-%lu does not exist", co->first, co->last); } - /* show dynamic rules */ - if (co->do_dynamic && ndyn) { - sbuf_printf(out, "## Dynamic rules (%d):\n", ndyn); +#undef NEXT + + return exitval; +} + +/* decompile dynamic rules */ +int +decompile_dynamic_rules(void *data, int nbytes, struct sbuf *out, struct cmdline_opts *co) +{ + struct ip_fw *r = data; + ipfw_dyn_rule *dynrules, *d; + int exitval = EX_OK; + + int bcwidth, n, pcwidth, width; + int ndyn; /* number of dynamic rules */ + uint8_t set; + + /* + * Count dynamic rules. This is easier as they have + * fixed size. + */ + dynrules = (ipfw_dyn_rule *)r ; + ndyn = nbytes / sizeof *dynrules; + + if (ndyn == 0) + return exitval; + + /* if showing stats, figure out column widths ahead of time */ - for (n = 0, d = dynrules; n < ndyn; n++, d++) { - /* skip boundaries */ - if (r->rulenum < co->first) + bcwidth = pcwidth = 0; + for (n = 0, d = dynrules; n < ndyn; n++, d++) { + if (co->use_set) { + /* skip rules from another set */ + bcopy((char *)&d->rule + sizeof(uint16_t), + &set, sizeof(uint8_t)); + if (set != co->use_set - 1) continue; - if (r->rulenum > co->last) - break; + } + width = snprintf(NULL, 0, "%llu", + align_uint64(&d->pcnt)); + if (width > pcwidth) + pcwidth = width; + + width = snprintf(NULL, 0, "%llu", + align_uint64(&d->bcnt)); + if (width > bcwidth) + bcwidth = width; + } + + /* show dynamic rules */ + sbuf_printf(out, "## Dynamic rules (%d):\n", ndyn); - if (co->use_set) { - bcopy((char *)&d->rule + sizeof(uint16_t), - &set, sizeof(uint8_t)); - if (set != co->use_set - 1) - continue; - } + for (n = 0, d = dynrules; n < ndyn; n++, d++) { + /* skip boundaries */ + if (r->rulenum < co->first) + continue; + if (r->rulenum > co->last) + break; - show_dyn_ipfw(d, pcwidth, bcwidth, out, co); + if (co->use_set) { + bcopy((char *)&d->rule + sizeof(uint16_t), + &set, sizeof(uint8_t)); + if (set != co->use_set - 1) + continue; } + + show_dyn_ipfw(d, pcwidth, bcwidth, out, co); } -#undef NEXT - return exitval; } @@ -1867,7 +1882,7 @@ void *data = NULL; int nbytes; - const int ocmd = co->do_pipe ? IP_DUMMYNET_GET : IP_FW_GET; + int ocmd = IP_FW_GET; /* default command is request static rules */ int nalloc = 1024; /* start somewhere... */ if (co->test_only) { @@ -1875,6 +1890,12 @@ return; } + /* get pipes or dynamic rules according command options */ + if (co->do_pipe) + ocmd = IP_DUMMYNET_GET; + else if (co->do_dynamic) + ocmd = IP_FW_DYN_GET; + ac--; av++; @@ -1890,7 +1911,10 @@ co->do_pipe ? "DUMMYNET" : "FW"); } - exitval = ipfw_list_decompile(data, nbytes, out, co); + if (co->do_dynamic) + exitval = decompile_dynamic_rules(data, nbytes, out, co); + else + exitval = decompile_static_rules(data, nbytes, out, co); /* free resources */ free(data); ==== //depot/projects/soc2009/marta_ipfw/src/sbin/ipfw/ipfw2.h#3 (text+ko) ==== @@ -20,6 +20,8 @@ * $FreeBSD: src/sbin/ipfw/ipfw2.h,v 1.9 2009/06/24 22:57:07 oleg Exp $ */ +#include <netinet/in.h> + /* * Options that can be set on the command line. * When reading commands from a file, a subset of the options can also @@ -262,7 +264,8 @@ extern void ipfw_add_compile_str(char *cmdstr, uint32_t *rulebuf, int *rulesize); struct ip_fw; extern void decompile_rule(struct ip_fw *rule, int pcwidth, int bcwidth, struct sbuf *out, struct cmdline_opts *co); -extern int ipfw_list_decompile(void *data, int nbytes, struct sbuf *out, struct cmdline_opts *co); +extern int decompile_static_rules(void *data, int nbytes, struct sbuf *out, struct cmdline_opts *co); +extern int decompile_dynamic_rules(void *data, int nbytes, struct sbuf *out, struct cmdline_opts *co); /* convert a rule in ac, av format, as required by the internal compilation process */ extern char **strtoargs(char *arg, int *ac); ==== //depot/projects/soc2009/marta_ipfw/src/sys/netinet/in.h#2 (text+ko) ==== @@ -443,6 +443,7 @@ #define IP_ONESBCAST 23 /* bool: send all-ones broadcast */ #define IP_BINDANY 24 /* bool: allow bind to any address */ +#define IP_FW_DYN_GET 39 /* get dynamic rule chain */ #define IP_FW_TABLE_ADD 40 /* add entry */ #define IP_FW_TABLE_DEL 41 /* delete entry */ #define IP_FW_TABLE_FLUSH 42 /* flush table */ @@ -453,7 +454,7 @@ #define IP_FW_DEL 51 /* delete a firewall rule from chain */ #define IP_FW_FLUSH 52 /* flush firewall rule chain */ #define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */ -#define IP_FW_GET 54 /* get entire firewall rule chain */ +#define IP_FW_GET 54 /* get static rule chain */ #define IP_FW_RESETLOG 55 /* reset logging counters */ #define IP_FW_NAT_CFG 56 /* add/config a nat rule */ ==== //depot/projects/soc2009/marta_ipfw/src/sys/netinet/ipfw/ip_fw2.c#3 (text+ko) ==== @@ -4644,7 +4644,7 @@ } /* - * Copy the static and dynamic rules to the supplied buffer + * Copy the static rules to the supplied buffer * and return the amount of space actually used. */ static size_t @@ -4683,6 +4683,23 @@ } } IPFW_RUNLOCK(chain); + return (bp - (char *)buf); +} + +/* + * Copy the dynamic rules to the supplied buffer + * and return the amount of space actually used. + */ +static size_t +ipfw_getdynrules(struct ip_fw_chain *chain, void *buf, size_t space) +{ + char *bp = buf; + char *ep = bp + space; + int i; + time_t boot_seconds; + + boot_seconds = boottime.tv_sec; + /* XXX this can take a long time and locking will block packet flow */ if (V_ipfw_dyn_v) { ipfw_dyn_rule *p, *last = NULL; @@ -4724,7 +4741,6 @@ return (bp - (char *)buf); } - /** * {set|get}sockopt parser. */ @@ -4733,7 +4749,7 @@ { #define RULE_MAXSIZE (256*sizeof(u_int32_t)) int error; - size_t size; + size_t size = 0; struct ip_fw *buf, *rule; u_int32_t rulenum[2]; @@ -4757,10 +4773,8 @@ switch (sopt->sopt_name) { case IP_FW_GET: /* - * pass up a copy of the current rules. Static rules - * come first (the last of which has number IPFW_DEFAULT_RULE), - * followed by a possibly empty list of dynamic rule. - * The last dynamic rule has NULL in the "next" field. + * Pass up a copy of the current static rules. + * The last staic rule has number IPFW_DEFAULT_RULE. * * Note that the calculated size is used to bound the * amount of data returned to the user. The rule set may @@ -4768,8 +4782,6 @@ * data in which case we'll just return what fits. */ size = V_static_len; /* size of static rules */ - if (V_ipfw_dyn_v) /* add size of dyn.rules */ - size += (V_dyn_count * sizeof(ipfw_dyn_rule)); if (size >= sopt->sopt_valsize) break; @@ -4784,6 +4796,27 @@ free(buf, M_TEMP); break; + case IP_FW_DYN_GET: + /* + * Pass up a copy of the current dynamic rules. + * The last dynamic rule has NULL in the "next" field. + */ + if (V_ipfw_dyn_v) /* size of dyn. rules */ + size = (V_dyn_count * sizeof(ipfw_dyn_rule)); + + if (size >= sopt->sopt_valsize) + break; + /* + * XXX todo: if the user passes a short length just to know + * how much room is needed, do not bother filling up the + * buffer, just jump to the sooptcopyout. + */ + buf = malloc(size, M_TEMP, M_WAITOK); + error = sooptcopyout(sopt, buf, + ipfw_getdynrules(&V_layer3_chain, buf, size)); + free(buf, M_TEMP); + break; + case IP_FW_FLUSH: /* * Normally we cannot release the lock on each iteration. ==== //depot/projects/soc2009/marta_ipfw/src/sys/netinet/raw_ip.c#2 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/netinet/raw_ip.c,v 1.220 2009/08/01 19:26:27 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/netinet/raw_ip.c,v 1.219 2009/07/16 21:13:04 rwatson Exp $"); #include "opt_inet6.h" #include "opt_ipsec.h" @@ -519,6 +519,7 @@ case IP_FW_ADD: /* ADD actually returns the body... */ case IP_FW_GET: + case IP_FW_DYN_GET: case IP_FW_TABLE_GETSIZE: case IP_FW_TABLE_LIST: case IP_FW_NAT_GET_CONFIG:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908170919.n7H9JedE027727>