| Summary: | Patch to add support to ipfw for per rule overriding of dynamic keep-state rule expiration lifetimes | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | agifford | ||||||||
| Component: | kern | Assignee: | Luigi Rizzo <luigi> | ||||||||
| Status: | Closed FIXED | ||||||||||
| Severity: | Affects Only Me | ||||||||||
| Priority: | Normal | ||||||||||
| Version: | 4.1.1-STABLE | ||||||||||
| Hardware: | Any | ||||||||||
| OS: | Any | ||||||||||
| Attachments: |
|
||||||||||
Responsible Changed From-To: freebsd-bugs->luigi Over to ipfw maintainer. Looks like this proposed patch (PR 22065) is still open. I suppose that means no one has decided whether it is useful or not, or (far more likely) folks are extremely busy doing other fun and useful stuff for FreeBSD. The patch in the PR is still mostly valid for FreeBSD 4.2-STABLE with a few line offset changes. I've got an updated version of the patch against 4.2-STABLE as of 17 FEB 2001 at the following web address: http://www.aarongifford.com/computers/ipfwpatch.html I have been using the patch successfully on several moderate-traffic hosts with no noticable problems. I do still have two questions that no one has yet answered. Still, it would be nice to know the following (with regard to the patch): 1. Am I safe using the union fw_un in the ip_fw structure (in ip_fw.h) to store the dynamic rule's lifetime setting or will this overlap with one of the other uses of that union and thus require that I modify the patch to create a new structure member for storing the setting? 2. Am I correct in assuming that in ip_fw.c at roughly line 800 where UDP and TCP matches to the dynamic rule extend the rule expiration by the dyn_syn_lifetime amount that this should instead only extend TCP matches by dyn_syn_lifetime and should extend UDP matches by dyn_short_lifetime instead? I believe this to be the case. The snippet of code from ip_fw.c in question looks like (beginning at line 800 of ip_fw.c as of FreeBSD 4.2-STABLE on 17 FEB 2001): } bzero (r, sizeof (*r) ); if (mask) r->mask = *mask ; r->id = *id ; r->expire = time_second + dyn_syn_lifetime ; /*<<<THIS LINE<<<*/ r->chain = chain ; r->type = ((struct ip_fw_ext *)chain->rule)->dyn_type ; r->bucket = i ; r->next = ipfw_dyn_v[i] ; ipfw_dyn_v[i] = r ; dyn_count++ ; DEB(printf("-- add entry 0x%08x %d -> 0x%08x %d, %d left\n", (r->id.src_ip), (r->id.src_port), (r->id.dst_ip), (r->id.dst_port), dyn_count ); ) } I assume that the line above (flagged above with "<<<THIS LINE<<<") should instead read something like: r->expire = time_second + (r->id.proto == IPPROTO_TCP ? dyn_syn_lifetime : dyn_short_lifetime) ; My patch assumes that this is the case and modifies the behavior so that non-TCP rule match expiration lifetimes are incremented by the dyn_short_lifetime sysctl setting (if no per-rule lifetime is specified). I would appreciate any answers to the two above questions, question #1 in particular, as well as any other commentary or suggestions. Thanks, Aaron out. -- InfoWest, Inc. * 596 E. Tabernacle * St. George, UT 84790 Voice: 435-674-0165 * FAX: 435-674-9654 Web: www.infowest.com * E-mail: support@infowest.com I suggest this PR be closed in favor of the more up-to-date one (#28713) at: http://www.FreeBSD.org/cgi/query-pr.cgi?pr=kern/28713 Aaron out. State Changed From-To: open->closed this replicates kern/28713 and it is made almost completely unnecessary by ipfw2's keepalives. |
Hello, When using ipfw's dynamic stateful rules, while users CAN use the sysctl variables to control expiration times globally, it cannot yet be done on a rule-by-rule basis. The patch below fixes this, adding the ability to append "lifetime X" (where X is a number) to any keep-state rule. For keep-state rules that do NOT append this new option, the old behavior guided by the sysctl variables remains. For those rules that add this option, on a rule-by-rule basis the expiration time may be customized. While writing these patches, I came across what LOOKS like a bug but may not. In ip_fw.c, I noticed that both TCP and non-TCP keep-state rules are updated using the net.inet.ip.fw_syn_lifetime where I would think that non-TCP keep-state rules should instead be using the net.inet.ip.fw.dyn_short_lifetime variable instead. This patch also fixes this issue. If this is NOT a bug but is deliberate, I would encourage that it be documented as such. I believe it is around line 798 of ip_fw.c (at least on FreeBSD-4.1.1-STABLE as of 17 Oct. 2000). This patch also adds documentation for the "lifetime X" option to the ipfw man page. I have been using these patches on several moderate-traffic Internet hosts and on several firewall boxes, all running various versions of FreeBSD 4.0 and 4.1 for several months now with absolutely no problems at all. I belive these changes to be VERY stable. This change would be extremely useful. I use it right now like this: (This is a small subset of my rules, edited for this example) ipfw add check-state ### UDP filters: # Keep state on UDP sent to ICQ servers for up to 5 minutes # so ICQ clients won't keep getting disconnected: ipfw add pass udp from ${MYIP} to ${ICQ_NETWORK} out keep-state lifetime 300 # All other UDP will use the default net.inet.ip.fw.dyn_short_lifetime # expiration: ipfw add pass udp from ${MYIP} to any out keep-state ### TCP filters: # Drop bogus "established" traffic: ipfw add deny tcp from any to any established # Keep my SSH sessions around for up to a whole day: ipfw add pass tcp from ${MYIP} to any out setup keep-state lifetime 86400 # All other outgoing TCP gets the default expiration as set in the # system variable net.inet.ip.fw_syn_lifetime: ipfw add pass tcp from ${MYIP} to any out setup keep-state I really hope that this new feature will be adopted. It has been very useful. And that would also let me be more lazy -- I wouldn't have to patch my system after each cvsup. :) If the patch submitted below (in the "Fix to the problem if known:" part) doesn't come through clearly, email me and I'll email the patch to you. Sincerely, Aaron Gifford Fix: struct ip_fw_chain { LIST_ENTRY(ip_fw_chain) chain; @@ -147,6 +149,7 @@ struct ipfw_flow_id mask ; struct ip_fw_chain *chain ; /* pointer to parent rule */ u_int32_t type ; /* rule type */ + u_int32_t lifetime ; /* per-rule specified lifetime */ u_int32_t expire ; /* expire time */ u_int64_t pcnt, bcnt; /* match counters */ u_int32_t bucket ; /* which bucket in hash table */ How-To-Repeat: This is a feature request