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>