Date: Wed, 6 Jun 2012 18:00:20 +0000 (UTC) From: Oleg Bulyzhin <oleg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r236692 - stable/9/sys/netinet/ipfw Message-ID: <201206061800.q56I0Kem029818@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206061800.q56I0Kem029818>