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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to