--- /usr/src/sys/netinet/ip_fw.h.orig Tue Oct 30 21:46:00 2001 +++ /usr/src/sys/netinet/ip_fw.h Wed Oct 31 11:11:40 2001 @@ -92,6 +92,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 */ @@ -132,6 +133,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; @@ -159,6 +161,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 lifetime */ u_int32_t expire; /* expire time */ u_int64_t pcnt; /* packet match counters */ u_int64_t bcnt; /* byte match counters */ --- /usr/src/sys/netinet/ip_fw.c.orig Wed Oct 3 19:56:01 2001 +++ /usr/src/sys/netinet/ip_fw.c Wed Oct 31 11:08:10 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 Tue Oct 30 21:45:34 2001 +++ /usr/src/sbin/ipfw/ipfw.c Wed Oct 31 11:15:35 2001 @@ -377,6 +377,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) @@ -860,7 +862,7 @@ " ipoptions [!]{ssrr|lsrr|rr|ts}, ...\n" " tcpoptions [!]{mss|window|sack|ts|cc}, ...\n" " icmptypes {type[, type]}...\n" -" keep-state [method]\n" +" keep-state [method] [lifetime ]\n" " pipeconfig:\n" " {bw|bandwidth} {bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n" " {bw|bandwidth} interface_name\n" @@ -1894,6 +1896,15 @@ if (ac > 0 && (type = atoi(*av)) != 0) { (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--; + } } } else if (!strncmp(*av, "bridged", strlen(*av))) { rule.fw_flg |= IP_FW_BRIDGED; --- /usr/src/sbin/ipfw/ipfw.8.orig Sat Oct 27 23:09:34 2001 +++ /usr/src/sbin/ipfw/ipfw.8 Wed Oct 31 11:08:10 2001 @@ -620,18 +620,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