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>
index | next in thread | previous in thread | raw e-mail
:
: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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212142209.gBEM9D8p002479>
