PERFORCE change 167434 for review
Marta Carbone
marta at FreeBSD.org
Mon Aug 17 09:19:41 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167434
Change 167434 by marta at 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:
More information about the p4-projects
mailing list