From owner-freebsd-arch Tue Nov 23 22:34:28 1999 Delivered-To: freebsd-arch@freebsd.org Received: from ns1.yes.no (ns1.yes.no [195.204.136.10]) by hub.freebsd.org (Postfix) with ESMTP id F125C15516 for ; Tue, 23 Nov 1999 22:34:19 -0800 (PST) (envelope-from eivind@bitbox.follo.net) Received: from bitbox.follo.net (bitbox.follo.net [195.204.143.218]) by ns1.yes.no (8.9.3/8.9.3) with ESMTP id HAA25320 for ; Wed, 24 Nov 1999 07:34:18 +0100 (CET) Received: (from eivind@localhost) by bitbox.follo.net (8.8.8/8.8.6) id HAA32120 for freebsd-arch@freebsd.org; Wed, 24 Nov 1999 07:34:18 +0100 (MET) Received: from green.dyndns.org (localhost [127.0.0.1]) by hub.freebsd.org (Postfix) with ESMTP id 230F615516; Tue, 23 Nov 1999 22:33:45 -0800 (PST) (envelope-from green@FreeBSD.org) Received: from localhost (green@localhost [127.0.0.1]) by green.dyndns.org (8.9.3/8.9.3) with ESMTP id BAA43025; Wed, 24 Nov 1999 01:33:04 -0500 (EST) (envelope-from green@FreeBSD.org) Date: Wed, 24 Nov 1999 01:33:04 -0500 (EST) From: Brian Fundakowski Feldman X-Sender: green@green.dyndns.org To: ipfw@freebsd.org Cc: arch@freebsd.org Subject: new IPFW Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG I've finally sat myself down to take the first step in getting the new IPFW done. I'll start by listing some of the different ideas I've had, CC'd to arch@ so that I pick up the audience of people I need. First of all, what was done right about the old IPFW? The basic architecture is nice; a chain of rules is quite efficient, but can be improved upon with basic optimization techniques, which should be done. The syntax is pretty nice, and IPFW is really very fast. It is called by a hook so was easy to become a KLD. Now, the new IPFW could directly replace the old IPFW given that 1) it uses the same entry point, and 2) uses the same API. The API for calling IPFW per-packet itself is not bad. There are many things to improve upon. The old IPFW is very static and limited in certain regards. It uses a monolithic "rule" struct to store everything related to that rule, which is obviously not the right thing to do. There are arbitrary limits on rules because of this, and it makes the API pretty sickening. So what can be done better than the old IPFW? First of all, it should be easy to retrieve a rule and change it. I should be able get, for instance, rule 1000 (in old IPFW format, of course) 1000 deny all from 127.0.0.0/24 to any and replace it with 1000 deny all from 127.0.0.0/8 to any. This would require a retrieval, deletion, and addition under the current IPFW user API. Instead, there should be an API call that woul effectively say "change rule 1000's destination address netmask to /8". I also want to be able to make things nicer to do. One, a certain amount of state should be able to be stored, allowing stateful operations in IPFW where previously there were none. Commands should be more dynamic; all the old rule actions should be supported (pass, deny, fwd, divert, pipe, et al), whereas new ones should be easy to add by PIM (Pluggable IPFW Modules? =). Perhaps it would be nice to have a real "branch" action instead of using more hackish gotos, which can be terminated with deny all from any to any (which should be a synonym for "end"; you should be able to write procedures in IPFW). All actions except for deny should have a "continue" option, where the packet matching would both match that rule and follow its action, but also pass on to the next rule. This would obsolete the never-working- anyway "tee" action, and make things much easier, if thought about properly. To cut down on number of rules (that basically go pass such-and- such, deny other-such) with redundant information, which would of course take up less memory and processor time, each "match" type could be negated, such as, with a default-to-pass rule set, "deny [implicit all] ( src [alt:from] 127.0.0.0/8 or dest [alt:to] 127.0.0.8 ) and not interface lo0". This would allow actual logic in rules, albeit with slightly more complexity in the IPFW implementation in the kernel. This would be a huge gain for the administrator of the firewall, in that {,s}he could use a more natural programming syntax, rather than the current, simplistic, absolutely non-programmable (but klugeable) IPFW. For the matching rules themselves, they should be dynamic and possibly object-oriented. I envision something like this: struct ipfw_rule { int rule_number; /* maybe name alias, too? :) */ u_int32_t rule_options; /* for what doesn't fit in the action */ rule_action *action; /* action is an object and contains ancillary data */ SLIST_HEAD(, match_type) matches; /* must match all of these in the null-terminated list to match the rule */ struct irstats { u_int64_t matches; etc... } stats; }; The match_type could consist of something like: SLIST_FOREACH(matchrule, rule->matches, rule_list_entry) { if (!matchrule->dispatch(matchrule, packet, other info)) return 0; } passed all matches. action.... Where matcher_dispatch would read the match object, which would be inherited from the base type: struct base_matchrule { match_func_t *dispatch; }; and other types would be something like { struct address_matchrule { match_func_t *dispatch; u_int32_t flags; /* source/dest, IS or NOT, etc. */ struct sockaddr_maxsize addr; /* support in and in6 */ }; And this would be the object-oriented architecture part. I'm going to wrap this up since I'm up quite late (well, only 1:30, but I'm still a growing person...), and I don't want to start to get too incoherent. Thank you for your time and attention with my IPFW ideas, and please send comments and ideas to me; heck, I'd love to start a long discussion about this, so we can flesh everything out :) -- Brian Fundakowski Feldman \ FreeBSD: The Power to Serve! / green@FreeBSD.org `------------------------------' To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message