svn commit: r236692 - stable/9/sys/netinet/ipfw
Oleg Bulyzhin
oleg at FreeBSD.org
Wed Jun 6 18:00:26 UTC 2012
Author: oleg
Date: Wed Jun 6 18:00:19 2012
New Revision: 236692
URL: http://svn.freebsd.org/changeset/base/236692
Log:
MFC: r232272, r232273
- lookup_dyn_rule_locked(): style(9) cleanup
- Refresh dynamic tcp rule only if both sides answered keepalive packets.
- Remove some useless assignments.
Modified:
stable/9/sys/netinet/ipfw/ip_fw_dynamic.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/netinet/ipfw/ip_fw_dynamic.c
==============================================================================
--- stable/9/sys/netinet/ipfw/ip_fw_dynamic.c Wed Jun 6 17:28:46 2012 (r236691)
+++ stable/9/sys/netinet/ipfw/ip_fw_dynamic.c Wed Jun 6 18:00:19 2012 (r236692)
@@ -390,72 +390,68 @@ ipfw_remove_dyn_children(struct ip_fw *r
IPFW_DYN_UNLOCK();
}
-/**
- * lookup a dynamic rule, locked version
+/*
+ * Lookup a dynamic rule, locked version.
*/
static ipfw_dyn_rule *
lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
struct tcphdr *tcp)
{
/*
- * stateful ipfw extensions.
- * Lookup into dynamic session queue
+ * Stateful ipfw extensions.
+ * Lookup into dynamic session queue.
*/
#define MATCH_REVERSE 0
#define MATCH_FORWARD 1
#define MATCH_NONE 2
#define MATCH_UNKNOWN 3
int i, dir = MATCH_NONE;
- ipfw_dyn_rule *prev, *q=NULL;
+ ipfw_dyn_rule *prev, *q = NULL;
IPFW_DYN_LOCK_ASSERT();
if (V_ipfw_dyn_v == NULL)
- goto done; /* not found */
- i = hash_packet( pkt );
- for (prev=NULL, q = V_ipfw_dyn_v[i] ; q != NULL ; ) {
+ goto done; /* not found */
+ i = hash_packet(pkt);
+ for (prev = NULL, q = V_ipfw_dyn_v[i]; q != NULL;) {
if (q->dyn_type == O_LIMIT_PARENT && q->count)
goto next;
- if (TIME_LEQ( q->expire, time_uptime)) { /* expire entry */
+ if (TIME_LEQ(q->expire, time_uptime)) { /* expire entry */
UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
continue;
}
- if (pkt->proto == q->id.proto &&
- q->dyn_type != O_LIMIT_PARENT) {
- if (IS_IP6_FLOW_ID(pkt)) {
- if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
- &(q->id.src_ip6)) &&
- IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
- &(q->id.dst_ip6)) &&
+ if (pkt->proto != q->id.proto || q->dyn_type == O_LIMIT_PARENT)
+ goto next;
+
+ if (IS_IP6_FLOW_ID(pkt)) {
+ if (IN6_ARE_ADDR_EQUAL(&pkt->src_ip6, &q->id.src_ip6) &&
+ IN6_ARE_ADDR_EQUAL(&pkt->dst_ip6, &q->id.dst_ip6) &&
pkt->src_port == q->id.src_port &&
- pkt->dst_port == q->id.dst_port ) {
+ pkt->dst_port == q->id.dst_port) {
+ dir = MATCH_FORWARD;
+ break;
+ }
+ if (IN6_ARE_ADDR_EQUAL(&pkt->src_ip6, &q->id.dst_ip6) &&
+ IN6_ARE_ADDR_EQUAL(&pkt->dst_ip6, &q->id.src_ip6) &&
+ pkt->src_port == q->id.dst_port &&
+ pkt->dst_port == q->id.src_port) {
+ dir = MATCH_REVERSE;
+ break;
+ }
+ } else {
+ if (pkt->src_ip == q->id.src_ip &&
+ pkt->dst_ip == q->id.dst_ip &&
+ pkt->src_port == q->id.src_port &&
+ pkt->dst_port == q->id.dst_port) {
dir = MATCH_FORWARD;
break;
- }
- if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
- &(q->id.dst_ip6)) &&
- IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
- &(q->id.src_ip6)) &&
- pkt->src_port == q->id.dst_port &&
- pkt->dst_port == q->id.src_port ) {
- dir = MATCH_REVERSE;
- break;
- }
- } else {
- if (pkt->src_ip == q->id.src_ip &&
- pkt->dst_ip == q->id.dst_ip &&
- pkt->src_port == q->id.src_port &&
- pkt->dst_port == q->id.dst_port ) {
- dir = MATCH_FORWARD;
- break;
- }
- if (pkt->src_ip == q->id.dst_ip &&
- pkt->dst_ip == q->id.src_ip &&
- pkt->src_port == q->id.dst_port &&
- pkt->dst_port == q->id.src_port ) {
- dir = MATCH_REVERSE;
- break;
- }
+ }
+ if (pkt->src_ip == q->id.dst_ip &&
+ pkt->dst_ip == q->id.src_ip &&
+ pkt->src_port == q->id.dst_port &&
+ pkt->dst_port == q->id.src_port) {
+ dir = MATCH_REVERSE;
+ break;
}
}
next:
@@ -463,45 +459,55 @@ next:
q = q->next;
}
if (q == NULL)
- goto done; /* q = NULL, not found */
+ goto done; /* q = NULL, not found */
- if ( prev != NULL) { /* found and not in front */
+ if (prev != NULL) { /* found and not in front */
prev->next = q->next;
q->next = V_ipfw_dyn_v[i];
V_ipfw_dyn_v[i] = q;
}
if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
- u_char flags = pkt->_flags & (TH_FIN|TH_SYN|TH_RST);
+ uint32_t ack;
+ u_char flags = pkt->_flags & (TH_FIN | TH_SYN | TH_RST);
#define BOTH_SYN (TH_SYN | (TH_SYN << 8))
#define BOTH_FIN (TH_FIN | (TH_FIN << 8))
- q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8);
- switch (q->state) {
- case TH_SYN: /* opening */
+#define TCP_FLAGS (TH_FLAGS | (TH_FLAGS << 8))
+#define ACK_FWD 0x10000 /* fwd ack seen */
+#define ACK_REV 0x20000 /* rev ack seen */
+
+ q->state |= (dir == MATCH_FORWARD) ? flags : (flags << 8);
+ switch (q->state & TCP_FLAGS) {
+ case TH_SYN: /* opening */
q->expire = time_uptime + V_dyn_syn_lifetime;
break;
case BOTH_SYN: /* move to established */
- case BOTH_SYN | TH_FIN : /* one side tries to close */
- case BOTH_SYN | (TH_FIN << 8) :
- if (tcp) {
+ case BOTH_SYN | TH_FIN: /* one side tries to close */
+ case BOTH_SYN | (TH_FIN << 8):
#define _SEQ_GE(a,b) ((int)(a) - (int)(b) >= 0)
- u_int32_t ack = ntohl(tcp->th_ack);
- if (dir == MATCH_FORWARD) {
- if (q->ack_fwd == 0 || _SEQ_GE(ack, q->ack_fwd))
- q->ack_fwd = ack;
- else { /* ignore out-of-sequence */
- break;
+ if (tcp == NULL)
+ break;
+
+ ack = ntohl(tcp->th_ack);
+ if (dir == MATCH_FORWARD) {
+ if (q->ack_fwd == 0 ||
+ _SEQ_GE(ack, q->ack_fwd)) {
+ q->ack_fwd = ack;
+ q->state |= ACK_FWD;
}
- } else {
- if (q->ack_rev == 0 || _SEQ_GE(ack, q->ack_rev))
- q->ack_rev = ack;
- else { /* ignore out-of-sequence */
- break;
+ } else {
+ if (q->ack_rev == 0 ||
+ _SEQ_GE(ack, q->ack_rev)) {
+ q->ack_rev = ack;
+ q->state |= ACK_REV;
}
- }
}
- q->expire = time_uptime + V_dyn_ack_lifetime;
+ if ((q->state & (ACK_FWD | ACK_REV)) ==
+ (ACK_FWD | ACK_REV)) {
+ q->expire = time_uptime + V_dyn_ack_lifetime;
+ q->state &= ~(ACK_FWD | ACK_REV);
+ }
break;
case BOTH_SYN | BOTH_FIN: /* both sides closed */
@@ -531,9 +537,9 @@ next:
q->expire = time_uptime + V_dyn_short_lifetime;
}
done:
- if (match_direction)
+ if (match_direction != NULL)
*match_direction = dir;
- return q;
+ return (q);
}
ipfw_dyn_rule *
@@ -1076,10 +1082,12 @@ ipfw_tick(void * vnetx)
if (TIME_LEQ(q->expire, time_uptime))
continue; /* too late, rule expired */
- m = ipfw_send_pkt(NULL, &(q->id), q->ack_rev - 1,
- q->ack_fwd, TH_SYN);
- mnext = ipfw_send_pkt(NULL, &(q->id), q->ack_fwd - 1,
- q->ack_rev, 0);
+ m = (q->state & ACK_REV) ? NULL :
+ ipfw_send_pkt(NULL, &(q->id), q->ack_rev - 1,
+ q->ack_fwd, TH_SYN);
+ mnext = (q->state & ACK_FWD) ? NULL :
+ ipfw_send_pkt(NULL, &(q->id), q->ack_fwd - 1,
+ q->ack_rev, 0);
switch (q->id.addr_type) {
case 4:
@@ -1105,18 +1113,16 @@ ipfw_tick(void * vnetx)
break;
#endif
}
-
- m = mnext = NULL;
}
}
IPFW_DYN_UNLOCK();
- for (m = mnext = m0; m != NULL; m = mnext) {
+ for (m = m0; m != NULL; m = mnext) {
mnext = m->m_nextpkt;
m->m_nextpkt = NULL;
ip_output(m, NULL, NULL, 0, NULL, NULL);
}
#ifdef INET6
- for (m = mnext = m6; m != NULL; m = mnext) {
+ for (m = m6; m != NULL; m = mnext) {
mnext = m->m_nextpkt;
m->m_nextpkt = NULL;
ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
More information about the svn-src-stable-9
mailing list