--- /usr/src/sys/netinet/ip_fw.h.orig Tue Feb 20 04:39:17 2001 +++ /usr/src/sys/netinet/ip_fw.h Tue Sep 25 10:40:26 2001 @@ -74,6 +74,7 @@ u_short fu_skipto_rule; /* SKIPTO command rule number */ u_short fu_reject_code; /* REJECT response code */ struct sockaddr_in fu_fwd_ip; + u_int32_t fu_dyn_lifetime; /* Explicit dynamic rule lifetime */ } fw_un; u_char fw_prot; /* IP protocol */ /* @@ -122,6 +123,7 @@ #define fw_reject_code fw_un.fu_reject_code #define fw_pipe_nr fw_un.fu_pipe_nr #define fw_fwd_ip fw_un.fu_fwd_ip +#define fw_dyn_lifetime fw_un.fu_dyn_lifetime struct ip_fw_chain { LIST_ENTRY(ip_fw_chain) next; @@ -148,6 +150,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 */ --- /usr/src/sys/netinet/ip_fw.c.orig Sun Aug 26 17:22:44 2001 +++ /usr/src/sys/netinet/ip_fw.c Tue Sep 25 10:40:26 2001 @@ -733,7 +733,7 @@ break ; case TH_SYN | (TH_SYN << 8) : /* move to established */ - q->expire = time_second + dyn_ack_lifetime ; + q->expire = time_second + q->lifetime ; break ; case TH_SYN | (TH_SYN << 8) | TH_FIN : case TH_SYN | (TH_SYN << 8) | (TH_FIN << 8) : @@ -758,7 +758,7 @@ } } else { /* should do something for UDP and others... */ - q->expire = time_second + dyn_short_lifetime ; + q->expire = time_second + q->lifetime ; } if (match_direction) *match_direction = dir ; @@ -804,7 +804,14 @@ if (mask) r->mask = *mask ; r->id = *id ; - r->expire = time_second + dyn_syn_lifetime ; + r->lifetime = chain->rule->fw_dyn_lifetime ; + if (r->id.proto == IPPROTO_TCP) { + r->lifetime = r->lifetime ? r->lifetime : dyn_ack_lifetime ; + r->expire = time_second + dyn_syn_lifetime ; + } else { + r->lifetime = r->lifetime ? r->lifetime : dyn_short_lifetime ; + r->expire = time_second + r->lifetime ; + } r->chain = chain ; r->type = ((struct ip_fw_ext *)chain->rule)->dyn_type ; --- /usr/src/sbin/ipfw/ipfw.c.orig Wed Aug 1 02:15:35 2001 +++ /usr/src/sbin/ipfw/ipfw.c Tue Sep 25 10:40:26 2001 @@ -390,6 +390,8 @@ printf(" keep-state %d", (int)chain->next_rule_ptr); else printf(" keep-state"); + if (chain->fw_dyn_lifetime) + printf(" lifetime %d", (int)chain->fw_dyn_lifetime); } /* Direction */ if (chain->fw_flg & IP_FW_BRIDGED) @@ -844,6 +846,7 @@ " ipoptions [!]{ssrr|lsrr|rr|ts},...\n" " tcpoptions [!]{mss|window|sack|ts|cc},...\n" " icmptypes {type[,type]}...\n" +" keep-state [lifetime ]\n" " pipeconfig:\n" " {bw|bandwidth} {bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n" " {bw|bandwidth} interface_name\n" @@ -1838,6 +1841,15 @@ (int)rule.next_rule_ptr = type; av++; ac--; } + if (ac > 0 && !strncmp(*av, "lifetime", strlen(*av))) { + u_long lifetime ; + + av++; ac--; + if (ac > 0 && (lifetime = atoi(*av)) != 0) { + rule.fw_dyn_lifetime = lifetime; + av++; ac--; + } + } continue; } if (!strncmp(*av, "bridged", strlen(*av))) { --- /usr/src/sbin/ipfw/ipfw.8.orig Thu Aug 16 05:35:45 2001 +++ /usr/src/sbin/ipfw/ipfw.8 Tue Sep 25 10:40:26 2001 @@ -614,18 +614,38 @@ interface. .It Ar options : .Bl -tag -width indent -.It Cm keep-state Op Ar method +.It Xo Cm keep-state Op Ar method +.Op Cm lifetime Ar number +.Xc Upon a match, the firewall will create a dynamic rule, whose -default behaviour is to matching bidirectional traffic between +default behaviour is to match bidirectional traffic between source and destination IP/port using the same protocol. -The rule has a limited lifetime (controlled by a set of +The rule has a limited lifetime controlled by a set of .Xr sysctl 8 -variables), and the lifetime is refreshed every time a matching -packet is found. +variables that may be overridden on a per-rule basis. +The lifetime is refreshed each time a matching packet is +found. .Pp The actual behaviour can be modified by specifying a different .Ar method , although at the moment only the default one is specified. +.Pp +The default rule lifetime may be overridden for a specific +rule by appending +.Cm lifetime Ar number +to explicitly set the number of seconds for the dynamic rule +lifetime. +.Pp +For TCP rules, explicitly setting a rule lifetime overrides the +default setting stored in the +.Xr sysctl 8 +variable +.Em net.inet.ip.fw.dyn_ack_lifetime . +For non-TCP rules, it overrides the +.Xr sysctl 8 +variable +.Em net.inet.ip.fw.dyn_short_lifetime +instead. .It Cm bridged Matches only bridged packets. This can be useful for multicast or broadcast traffic, which