svn commit: r300143 - head/sys/netpfil/ipfw

Andrey V. Elsukov ae at FreeBSD.org
Wed May 18 12:53:23 UTC 2016


Author: ae
Date: Wed May 18 12:53:21 2016
New Revision: 300143
URL: https://svnweb.freebsd.org/changeset/base/300143

Log:
  Move protocol state handling code from lookup_dyn_rule_locked() function
  into dyn_update_proto_state(). This allows eliminate the second state
  lookup in the ipfw_install_state().
  Also remove MATCH_* macros, they are defined in ip_fw_private.h as enum.
  
  Obtained from:	Yandex LLC
  Sponsored by:	Yandex LLC

Modified:
  head/sys/netpfil/ipfw/ip_fw_dynamic.c

Modified: head/sys/netpfil/ipfw/ip_fw_dynamic.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_dynamic.c	Wed May 18 12:03:57 2016	(r300142)
+++ head/sys/netpfil/ipfw/ip_fw_dynamic.c	Wed May 18 12:53:21 2016	(r300143)
@@ -319,77 +319,15 @@ print_dyn_rule_flags(struct ipfw_flow_id
 #define TIME_LEQ(a,b)       ((int)((a)-(b)) <= 0)
 #define TIME_LE(a,b)       ((int)((a)-(b)) < 0)
 
-/*
- * Lookup a dynamic rule, locked version.
- */
-static ipfw_dyn_rule *
-lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int i, int *match_direction,
-    struct tcphdr *tcp)
+static void
+dyn_update_proto_state(ipfw_dyn_rule *q, const struct ipfw_flow_id *id,
+    const struct tcphdr *tcp, int dir)
 {
-	/*
-	 * 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 dir = MATCH_NONE;
-	ipfw_dyn_rule *prev, *q = NULL;
-
-	IPFW_BUCK_ASSERT(i);
-
-	for (prev = NULL, q = V_ipfw_dyn_v[i].head; q; prev = q, q = q->next) {
-		if (q->dyn_type == O_LIMIT_PARENT && q->count)
-			continue;
-
-		if (pkt->proto != q->id.proto || q->dyn_type == O_LIMIT_PARENT)
-			continue;
-
-		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) {
-				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 (q == NULL)
-		goto done;	/* q = NULL, not found */
-
-	if (prev != NULL) {	/* found and not in front */
-		prev->next = q->next;
-		q->next = V_ipfw_dyn_v[i].head;
-		V_ipfw_dyn_v[i].head = q;
-	}
-	if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
-		uint32_t ack;
-		u_char flags = pkt->_flags & (TH_FIN | TH_SYN | TH_RST);
+	uint32_t ack;
+	u_char flags;
 
+	if (id->proto == IPPROTO_TCP) {
+		flags = id->_flags & (TH_FIN | TH_SYN | TH_RST);
 #define BOTH_SYN	(TH_SYN | (TH_SYN << 8))
 #define BOTH_FIN	(TH_FIN | (TH_FIN << 8))
 #define	TCP_FLAGS	(TH_FLAGS | (TH_FLAGS << 8))
@@ -432,7 +370,8 @@ lookup_dyn_rule_locked(struct ipfw_flow_
 
 		case BOTH_SYN | BOTH_FIN:	/* both sides closed */
 			if (V_dyn_fin_lifetime >= V_dyn_keepalive_period)
-				V_dyn_fin_lifetime = V_dyn_keepalive_period - 1;
+				V_dyn_fin_lifetime =
+				    V_dyn_keepalive_period - 1;
 			q->expire = time_uptime + V_dyn_fin_lifetime;
 			break;
 
@@ -446,16 +385,86 @@ lookup_dyn_rule_locked(struct ipfw_flow_
 				printf("invalid state: 0x%x\n", q->state);
 #endif
 			if (V_dyn_rst_lifetime >= V_dyn_keepalive_period)
-				V_dyn_rst_lifetime = V_dyn_keepalive_period - 1;
+				V_dyn_rst_lifetime =
+				    V_dyn_keepalive_period - 1;
 			q->expire = time_uptime + V_dyn_rst_lifetime;
 			break;
 		}
-	} else if (pkt->proto == IPPROTO_UDP) {
+	} else if (id->proto == IPPROTO_UDP) {
 		q->expire = time_uptime + V_dyn_udp_lifetime;
 	} else {
 		/* other protocols */
 		q->expire = time_uptime + V_dyn_short_lifetime;
 	}
+}
+
+/*
+ * Lookup a dynamic rule, locked version.
+ */
+static ipfw_dyn_rule *
+lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int i, int *match_direction,
+    struct tcphdr *tcp)
+{
+	/*
+	 * Stateful ipfw extensions.
+	 * Lookup into dynamic session queue.
+	 */
+	ipfw_dyn_rule *prev, *q = NULL;
+	int dir;
+
+	IPFW_BUCK_ASSERT(i);
+
+	dir = MATCH_NONE;
+	for (prev = NULL, q = V_ipfw_dyn_v[i].head; q; prev = q, q = q->next) {
+		if (q->dyn_type == O_LIMIT_PARENT && q->count)
+			continue;
+
+		if (pkt->proto != q->id.proto || q->dyn_type == O_LIMIT_PARENT)
+			continue;
+
+		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) {
+				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 (q == NULL)
+		goto done;	/* q = NULL, not found */
+
+	if (prev != NULL) {	/* found and not in front */
+		prev->next = q->next;
+		q->next = V_ipfw_dyn_v[i].head;
+		V_ipfw_dyn_v[i].head = q;
+	}
+
+	/* update state according to flags */
+	dyn_update_proto_state(q, pkt, tcp, dir);
 done:
 	if (match_direction != NULL)
 		*match_direction = dir;
@@ -678,7 +687,7 @@ ipfw_install_state(struct ip_fw_chain *c
     ipfw_insn_limit *cmd, struct ip_fw_args *args, uint32_t tablearg)
 {
 	ipfw_dyn_rule *q;
-	int i;
+	int i, dir;
 
 	DEB(print_dyn_rule(&args->f_id, cmd->o.opcode, "install_state", "");)
 	
@@ -686,8 +695,7 @@ ipfw_install_state(struct ip_fw_chain *c
 
 	IPFW_BUCK_LOCK(i);
 
-	q = lookup_dyn_rule_locked(&args->f_id, i, NULL, NULL);
-
+	q = lookup_dyn_rule_locked(&args->f_id, i, &dir, NULL);
 	if (q != NULL) {	/* should never occur */
 		DEB(
 		if (last_log != time_uptime) {
@@ -786,7 +794,8 @@ ipfw_install_state(struct ip_fw_chain *c
 		IPFW_BUCK_UNLOCK(pindex);
 
 		IPFW_BUCK_LOCK(i);
-		q = add_dyn_rule(&args->f_id, i, O_LIMIT, (struct ip_fw *)parent);
+		q = add_dyn_rule(&args->f_id, i, O_LIMIT,
+		    (struct ip_fw *)parent);
 		if (q == NULL) {
 			/* Decrement index and notify caller */
 			IPFW_BUCK_UNLOCK(i);
@@ -807,9 +816,7 @@ ipfw_install_state(struct ip_fw_chain *c
 		return (1);	/* Notify caller about failure */
 	}
 
-	/* XXX just set lifetime */
-	lookup_dyn_rule_locked(&args->f_id, i, NULL, NULL);
-
+	dyn_update_proto_state(q, &args->f_id, NULL, dir);
 	IPFW_BUCK_UNLOCK(i);
 	return (0);
 }


More information about the svn-src-head mailing list