Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Dec 2002 14:09:13 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        "David O'Brien" <obrien@FreeBSD.ORG>
Cc:        current@FreeBSD.ORG
Subject:   Re: ipfw userland breaks again.
Message-ID:  <200212142209.gBEM9D8p002479@apollo.backplane.com>
References:  <200212142025.aa99706@salmon.maths.tcd.ie> <200212142038.gBEKcDVv029924@apollo.backplane.com> <20021214204426.GA62058@dragon.nuxi.com>

next in thread | previous in thread | raw e-mail | index | archive | help

:
:On Sat, Dec 14, 2002 at 12:38:13PM -0800, Matthew Dillon wrote:
:>     then, as usual, IPFW with the new kernel and
:>     old world fails utterly and now the fragging machine can't access the
:
:Hear hear!!  I am >< tempted to have /sbin/ipfw moved to src/sys.

    How about something like this (patch enclosed).  If there are no
    objections I will commit it along with a documentation update, and
    maybe also add some RC code give the sysad a chance to ipfw unbreak if
    ipfw otherwise fails during the boot sequence.

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>


Index: sbin/ipfw/ipfw2.c
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.18
diff -u -r1.18 ipfw2.c
--- sbin/ipfw/ipfw2.c	26 Nov 2002 22:53:14 -0000	1.18
+++ sbin/ipfw/ipfw2.c	14 Dec 2002 22:08:11 -0000
@@ -3307,6 +3307,30 @@
 		printf("Flushed all %s.\n", do_pipe ? "pipes" : "rules");
 }
 
+static void
+unbreak()
+{
+	if (!do_force && !do_quiet) { /* need to ask user */
+		int c;
+
+		printf("Are you sure? [yn] ");
+		fflush(stdout);
+		do {
+			c = toupper(getc(stdin));
+			while (c != '\n' && getc(stdin) != '\n')
+				if (feof(stdin))
+					return; /* and do not flush */
+		} while (c != 'Y' && c != 'N');
+		printf("\n");
+		if (c == 'N')	/* user said no */
+			return;
+	}
+	if (setsockopt(s, IPPROTO_IP, IP_FW_UNBREAK, NULL, 0) < 0)
+		err(EX_UNAVAILABLE, "setsockopt(IP_FW_UNBREAK)");
+	if (!do_quiet)
+		printf("Flushed all rules and installed a pass-through.\n");
+}
+
 static int
 ipfw_main(int ac, char **av)
 {
@@ -3398,6 +3422,8 @@
 		delete(ac, av);
 	else if (!strncmp(*av, "flush", strlen(*av)))
 		flush();
+	else if (!strncmp(*av, "unbreak", strlen(*av)))
+		unbreak();
 	else if (!strncmp(*av, "zero", strlen(*av)))
 		zero(ac, av);
 	else if (!strncmp(*av, "resetlog", strlen(*av)))
Index: sys/netinet/in.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.h,v
retrieving revision 1.73
diff -u -r1.73 in.h
--- sys/netinet/in.h	29 Oct 2002 16:46:13 -0000	1.73
+++ sys/netinet/in.h	14 Dec 2002 21:32:07 -0000
@@ -393,6 +393,7 @@
 #define	IP_FW_ZERO    		53   /* clear single/all firewall counter(s) */
 #define	IP_FW_GET     		54   /* get entire firewall rule chain */
 #define	IP_FW_RESETLOG		55   /* reset logging counters */
+#define	IP_FW_UNBREAK		56   /* flush and install a pass-thru rule */
 
 #define	IP_DUMMYNET_CONFIGURE	60   /* add/configure a dummynet pipe */
 #define	IP_DUMMYNET_DEL		61   /* delete a dummynet pipe from chain */
Index: sys/netinet/ip_fw2.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.19
diff -u -r1.19 ip_fw2.c
--- sys/netinet/ip_fw2.c	20 Nov 2002 19:07:27 -0000	1.19
+++ sys/netinet/ip_fw2.c	14 Dec 2002 21:41:52 -0000
@@ -2535,6 +2535,7 @@
 		break;
 
 	case IP_FW_FLUSH:
+	case IP_FW_UNBREAK:
 		/*
 		 * Normally we cannot release the lock on each iteration.
 		 * We could do it here only because we start from the head all
@@ -2551,6 +2552,22 @@
 		s = splimp();
 		free_chain(&layer3_chain, 0 /* keep default rule */);
 		splx(s);
+
+		/*
+		 * If unbreaking the rulechain, which a sysad may have to do
+		 * if IP_FW_ADD fails due to a userland/kernelland mismatch,
+		 * install a pass-through rule.
+		 */
+		if (sopt->sopt_name == IP_FW_UNBREAK) {
+			rule = (struct ip_fw *)rule_buf; /* XXX do a malloc */
+			bzero(rule, sizeof(*rule));
+			rule->rulenum = 2;
+			rule->cmd_len = 1;
+			rule->set = 1;
+			rule->cmd[0].len = 1;
+			rule->cmd[0].opcode = O_ACCEPT;
+			error = add_rule(&layer3_chain, rule);
+		}
 		break;
 
 	case IP_FW_ADD:
Index: sys/netinet/raw_ip.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.107
diff -u -r1.107 raw_ip.c
--- sys/netinet/raw_ip.c	20 Nov 2002 19:00:54 -0000	1.107
+++ sys/netinet/raw_ip.c	14 Dec 2002 21:33:58 -0000
@@ -399,6 +399,7 @@
 		case IP_FW_ADD:
 		case IP_FW_DEL:
 		case IP_FW_FLUSH:
+		case IP_FW_UNBREAK:
 		case IP_FW_ZERO:
 		case IP_FW_RESETLOG:
 			if (IPFW_LOADED)

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212142209.gBEM9D8p002479>