RFE/patch: Allow specification of default set number and number rules in ipfw2

Rolf Grossmann rg at progtech.net
Thu May 22 06:31:50 PDT 2003


Hi,

I have extended ipfw2 with 2 new options:

1. Allow a default set number to be specified for rules that don't have one.
2. Make ipfw number the rules read from a file instead of having the kernel
   pick the rule number.

That way, I can load a firewall rules file into an empty and disabled
set without having to specify numbers with every rule in the file and
then atomically switch the old and new rules with ipfw swap.

I'd now like to know, what are the chances of getting it integrated
with FreeBSD? Do you think it's useful? Should I file a PR (so it's
not forgotten, as it certainly won't go in before 5.1)?

The attached patch is against the latest -STABLE, but should be no
problem to fit with -CURRENT.

Let me know what you think.

Rolf

-------------- next part --------------
Index: ipfw.8
===================================================================
RCS file: /export/server/freebsd/FreeBSD/cvs/cvs/src/sbin/ipfw/ipfw.8,v
retrieving revision 1.63.2.33
diff -u -r1.63.2.33 ipfw.8
--- ipfw.8	4 Feb 2003 01:36:02 -0000	1.63.2.33
+++ ipfw.8	22 May 2003 12:31:43 -0000
@@ -54,7 +54,7 @@
 .Op Ar number ...
 .Pp
 .Nm
-.Op Fl q
+.Op Fl qN
 .Oo
 .Fl p Ar preproc
 .Oo Fl D
@@ -62,6 +62,7 @@
 .Oc
 .Op Fl U Ar macro
 .Oc
+.Op Fl S Ar set
 .Ar pathname
 .Sh DESCRIPTION
 The
@@ -271,7 +272,24 @@
 must be used.
 The file will be read line by line and applied as arguments to the
 .Nm
-utility.
+utility. By using
+.Fl S Ar set
+the default set number can be given for rules that don't specify one.
+Also, with the
+.Fl N
+flag, one can shift the rule numbering from the kernel to the
+.Nm
+utility. Rules will be numbered relative to the previous rule using the
+same stepsize as the kernel (taken from the sysctl variable
+.Ar net.inet.ip.fw.autoinc_step ) .
+If the first rule in the file is not explicitly numbered, it gets the
+number the kernel will pick (so if no rule in the file is numbered,
+the result will be the same with or without the option). Using this
+option allows rules to be loaded into a different, possibly disabled,
+set (e.g. using the
+.Fl S
+option), with numbers overlapping the existing rules by only giving a
+number for the first rule in the set.
 .Pp
 Optionally, a preprocessor can be specified using
 .Fl p Ar preproc
Index: ipfw2.c
===================================================================
RCS file: /export/server/freebsd/FreeBSD/cvs/cvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.4.2.12
diff -u -r1.4.2.12 ipfw2.c
--- ipfw2.c	14 Apr 2003 12:41:37 -0000	1.4.2.12
+++ ipfw2.c	22 May 2003 12:53:37 -0000
@@ -66,6 +66,8 @@
 		do_expired,		/* display expired dynamic rules */
 		do_compact,		/* show rules in compact mode */
 		show_sets,		/* display rule sets */
+		dflt_set,		/* default set to use in add rules */
+		rule_increment,		/* client-side rule number increment */
 		verbose;
 
 #define	IP_MASK_ALL	0xffffffff
@@ -2503,6 +2505,7 @@
 	 * go into actbuf[].
 	 */
 	static u_int32_t rulebuf[255], actbuf[255], cmdbuf[255];
+	static int next_rulenum = 0;
 
 	ipfw_insn *src, *dst, *cmd, *action, *prev;
 	ipfw_insn *first_cmd;	/* first match pattern */
@@ -2539,6 +2542,8 @@
 		av++;
 		ac--;
 	}
+	else if (rule_increment > 0)
+		rule->rulenum = next_rulenum;
 
 	/* [set N]	-- set number (0..30), optional */
 	if (ac > 1 && !strncmp(*av, "set", strlen(*av))) {
@@ -2548,6 +2553,8 @@
 		rule->set = set;
 		av += 2; ac -= 2;
 	}
+	else
+		rule->set = dflt_set;
 
 	/* [prob D]	-- match probability, optional */
 	if (ac > 1 && !strncmp(*av, "prob", strlen(*av))) {
@@ -3252,6 +3259,7 @@
 		err(EX_UNAVAILABLE, "getsockopt(%s)", "IP_FW_ADD");
 	if (!do_quiet)
 		show_ipfw(rule, 10, 10);
+	next_rulenum = rule->rulenum + rule_increment;
 }
 
 static void
@@ -3486,7 +3494,7 @@
 	pid_t	preproc = 0;
 	int	c;
 
-	while ((c = getopt(ac, av, "D:U:p:q")) != -1)
+	while ((c = getopt(ac, av, "D:U:p:qNS:")) != -1)
 		switch(c) {
 		case 'D':
 			if (!pflag)
@@ -3519,6 +3527,19 @@
 			qflag = 1;
 			break;
 
+		case 'N':
+			c = sizeof(rule_increment);
+			if (sysctlbyname("net.inet.ip.fw.autoinc_step",
+							 &rule_increment, &c, NULL, 0))
+				err(EX_UNAVAILABLE, "Can't get increment value");
+			break;
+			
+		case 'S':
+			dflt_set = atoi(optarg);
+			if (dflt_set < 0 || dflt_set > 30)
+				errx(EX_DATAERR, "illegal set %s", optarg);
+			break;
+
 		default:
 			errx(EX_USAGE, "bad arguments, for usage"
 			     " summary ``ipfw''");
@@ -3615,6 +3636,9 @@
 	s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 	if (s < 0)
 		err(EX_UNAVAILABLE, "socket");
+
+	dflt_set = 0;
+	rule_increment = 0;
 
 	/*
 	 * If the last argument is an absolute pathname, interpret it


More information about the freebsd-ipfw mailing list