Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jun 2014 08:40:39 GMT
From:      dpl@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r269431 - soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw
Message-ID:  <201406120840.s5C8edED014071@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dpl
Date: Thu Jun 12 08:40:37 2014
New Revision: 269431
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269431

Log:
  Added up to rule_skipto().
  

Modified:
  soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c
  soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h

Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c	Thu Jun 12 04:47:14 2014	(r269430)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c	Thu Jun 12 08:40:37 2014	(r269431)
@@ -780,7 +780,7 @@
  */
 static inline void
 set_match(struct ip_fw_args *args, int slot,
-	struct ip_fw_chain *chain)
+    struct ip_fw_chain *chain)
 {
 	args->rule.chain_id = chain->id;
 	args->rule.slot = slot + 1; /* we use 0 as a marker */
@@ -1625,116 +1625,21 @@
 				rule_ip4(&match, is_ipv4);
 				break;
 
-			case O_TAG: {
-				struct m_tag *mtag;
-				uint32_t tag = IP_FW_ARG_TABLEARG(cmd->arg1);
-
-				/* Packet is already tagged with this tag? */
-				mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL);
-
-				/* We have `untag' action when F_NOT flag is
-				 * present. And we must remove this mtag from
-				 * mbuf and reset `match' to zero (`match' will
-				 * be inversed later).
-				 * Otherwise we should allocate new mtag and
-				 * push it into mbuf.
-				 */
-				if (cmd->len & F_NOT) { /* `untag' action */
-					if (mtag != NULL)
-						m_tag_delete(m, mtag);
-					match = 0;
-				} else {
-					if (mtag == NULL) {
-						mtag = m_tag_alloc( MTAG_IPFW,
-						    tag, 0, M_NOWAIT);
-						if (mtag != NULL)
-							m_tag_prepend(m, mtag);
-					}
-					match = 1;
-				}
+			case O_TAG: 
+				rule_tag(&match, cmd, m);
 				break;
-			}
 
 			case O_FIB: /* try match the specified fib */
-				if (args->f_id.fib == cmd->arg1)
-					match = 1;
+				rule_fib(&match, args, cmd);
 				break;
 
-			case O_SOCKARG:	{
-#ifndef USERSPACE	/* not supported in userspace */
-				struct inpcb *inp = args->inp;
-				struct inpcbinfo *pi;
-				
-				if (is_ipv6) /* XXX can we remove this ? */
-					break;
-
-				if (proto == IPPROTO_TCP)
-					pi = &V_tcbinfo;
-				else if (proto == IPPROTO_UDP)
-					pi = &V_udbinfo;
-				else
-					break;
-
-				/*
-				 * XXXRW: so_user_cookie should almost
-				 * certainly be inp_user_cookie?
-				 */
-
-				/* For incomming packet, lookup up the 
-				inpcb using the src/dest ip/port tuple */
-				if (inp == NULL) {
-					inp = in_pcblookup(pi, 
-						src_ip, htons(src_port),
-						dst_ip, htons(dst_port),
-						INPLOOKUP_RLOCKPCB, NULL);
-					if (inp != NULL) {
-						tablearg =
-						    inp->inp_socket->so_user_cookie;
-						if (tablearg)
-							match = 1;
-						INP_RUNLOCK(inp);
-					}
-				} else {
-					if (inp->inp_socket) {
-						tablearg =
-						    inp->inp_socket->so_user_cookie;
-						if (tablearg)
-							match = 1;
-					}
-				}
-#endif /* !USERSPACE */
+			case O_SOCKARG:
+				rule_sockarg();
 				break;
-			}
-
-			case O_TAGGED: {
-				struct m_tag *mtag;
-				uint32_t tag = IP_FW_ARG_TABLEARG(cmd->arg1);
-
-				if (cmdlen == 1) {
-					match = m_tag_locate(m, MTAG_IPFW,
-					    tag, NULL) != NULL;
-					break;
-				}
 
-				/* we have ranges */
-				for (mtag = m_tag_first(m);
-				    mtag != NULL && !match;
-				    mtag = m_tag_next(m, mtag)) {
-					uint16_t *p;
-					int i;
-
-					if (mtag->m_tag_cookie != MTAG_IPFW)
-						continue;
-
-					p = ((ipfw_insn_u16 *)cmd)->ports;
-					i = cmdlen - 1;
-					for(; !match && i > 0; i--, p += 2)
-						match =
-						    mtag->m_tag_id >= p[0] &&
-						    mtag->m_tag_id <= p[1];
-				}
+			case O_TAGGED:
+				rule_tagged(&match, cmd, cmdlen, m);
 				break;
-			}
 				
 			/*
 			 * The second set of opcodes represents 'actions',
@@ -1779,99 +1684,30 @@
 			 */
 			case O_LIMIT:
 			case O_KEEP_STATE:
-				if (ipfw_install_state(f,
-				    (ipfw_insn_limit *)cmd, args, tablearg)) {
-					/* error or limit violation */
-					retval = IP_FW_DENY;
-					l = 0;	/* exit inner loop */
-					done = 1; /* exit outer loop */
-				}
-				match = 1;
+				rule_keep_state(&match, f, cmd, args, tablearg, &retval, &l, &done);
 				break;
 
 			case O_PROBE_STATE:
 			case O_CHECK_STATE:
-				/*
-				 * dynamic rules are checked at the first
-				 * keep-state or check-state occurrence,
-				 * with the result being stored in dyn_dir.
-				 * The compiler introduces a PROBE_STATE
-				 * instruction for us when we have a
-				 * KEEP_STATE (because PROBE_STATE needs
-				 * to be run first).
-				 */
-				if (dyn_dir == MATCH_UNKNOWN &&
-				    (q = ipfw_lookup_dyn_rule(&args->f_id,
-				     &dyn_dir, proto == IPPROTO_TCP ?
-					TCP(ulp) : NULL))
-					!= NULL) {
-					/*
-					 * Found dynamic entry, update stats
-					 * and jump to the 'action' part of
-					 * the parent rule by setting
-					 * f, cmd, l and clearing cmdlen.
-					 */
-					IPFW_INC_DYN_COUNTER(q, pktlen);
-					/* XXX we would like to have f_pos
-					 * readily accessible in the dynamic
-				         * rule, instead of having to
-					 * lookup q->rule.
-					 */
-					f = q->rule;
-					f_pos = ipfw_find_rule(chain,
-						f->rulenum, f->id);
-					cmd = ACTION_PTR(f);
-					l = f->cmd_len - f->act_ofs;
-					ipfw_dyn_unlock(q);
-					cmdlen = 0;
-					match = 1;
-					break;
-				}
-				/*
-				 * Dynamic entry not found. If CHECK_STATE,
-				 * skip to next rule, if PROBE_STATE just
-				 * ignore and continue with next opcode.
-				 */
-				if (cmd->opcode == O_CHECK_STATE)
-					l = 0;	/* exit inner loop */
-				match = 1;
+				rule_check_state(&match);
 				break;
 
 			case O_ACCEPT:
-				retval = 0;	/* accept */
-				l = 0;		/* exit inner loop */
-				done = 1;	/* exit outer loop */
+				rule_accept(&retval, &l, &done);
 				break;
 
 			case O_PIPE:
 			case O_QUEUE:
-				set_match(args, f_pos, chain);
-				args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
-				if (cmd->opcode == O_PIPE)
-					args->rule.info |= IPFW_IS_PIPE;
-				if (V_fw_one_pass)
-					args->rule.info |= IPFW_ONEPASS;
-				retval = IP_FW_DUMMYNET;
-				l = 0;          /* exit inner loop */
-				done = 1;       /* exit outer loop */
+				rule_queue(args, f_pos, chain, cmd, &retval, &l, &done);
 				break;
 
 			case O_DIVERT:
 			case O_TEE:
-				if (args->eh) /* not on layer 2 */
-				    break;
-				/* otherwise this is terminal */
-				l = 0;		/* exit inner loop */
-				done = 1;	/* exit outer loop */
-				retval = (cmd->opcode == O_DIVERT) ?
-					IP_FW_DIVERT : IP_FW_TEE;
-				set_match(args, f_pos, chain);
-				args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
+				rule_tee(&l, &done, &retval, cmd, args, f_pos, chain);
 				break;
 
 			case O_COUNT:
-				IPFW_INC_RULE_COUNTER(f, pktlen);
-				l = 0;		/* exit inner loop */
+				rule_count(&l, f, pktlen);
 				break;
 
 			case O_SKIPTO:

Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h
==============================================================================
--- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h	Thu Jun 12 04:47:14 2014	(r269430)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h	Thu Jun 12 08:40:37 2014	(r269431)
@@ -219,7 +219,6 @@
 }
 
 
-//XXX Speak with mentor about passing both dst_ip and src_ip.
 inline void
 rule_ip_dst_mask(int *match, int is_ipv4, ipfw_insn *cmd, int cmdlen, struct in_addr *dst_ip, struct in_addr *src_ip)
 {
@@ -585,9 +584,8 @@
 	    verify_path(src_ip, NULL, args->f_id.fib)));
 }
 
-// XXX typeof(m)?
 inline void
-rule_antispoof(int *match, struct ifnet *oif, u_int hlen, int is_ipv4, int is_ipv6, struct in_addr *src_ip, struct ip_fw_args *args, m)
+rule_antispoof(int *match, struct ifnet *oif, u_int hlen, int is_ipv4, int is_ipv6, struct in_addr *src_ip, struct ip_fw_args *args, struct mbuf *m)
 {
 	/* Outgoing packets automatically pass/match */
 	if (oif == NULL && hlen > 0 &&
@@ -809,42 +807,139 @@
  * The second sets of opcodes. They represent the actions of a rule.
  */
 inline void
-rule_keep_state(int *match, f, ipfw_insn *cmd, struct ip_fw_args *args, uint32_t *tablearg, retval, l, done)
+rule_keep_state(int *match, struct ip_fw *f, ipfw_insn *cmd, struct ip_fw_args *args, uint32_t *tablearg, int *retval, int *l, int *done)
 {
+	if (ipfw_install_state(f,
+	    (ipfw_insn_limit *)cmd, args, tablearg)) {
+		/* error or limit violation */
+		*retval = IP_FW_DENY;
+		*l = 0;	/* exit inner loop */
+		*done = 1; /* exit outer loop */
+	}
+	*match = 1;
 }
 
+/* XXX typeof dyn_dir? */
+/* XXX typeof q? */
 inline void
-rule_check_state(int *match, dyn_dir, q, struct ip_fw_args *args, uint8_t proto, void *void *ulp, pktlen, f, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, int *cmdlen, l)
+rule_check_state(int *match, dyn_dir, q, struct ip_fw_args *args, uint8_t proto, void *ulp, int pktlen, struct ip_fw *f, int *f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, int *cmdlen, int *l)
 {
+	/*
+	 * dynamic rules are checked at the first
+	 * keep-state or check-state occurrence,
+	 * with the result being stored in dyn_dir.
+	 * The compiler introduces a PROBE_STATE
+	 * instruction for us when we have a
+	 * KEEP_STATE (because PROBE_STATE needs
+	 * to be run first).
+	 */
+	if (dyn_dir == MATCH_UNKNOWN &&
+	    (q = ipfw_lookup_dyn_rule(&args->f_id,
+	     &dyn_dir, proto == IPPROTO_TCP ?
+		TCP(ulp) : NULL))
+		!= NULL) {
+		/*
+		 * Found dynamic entry, update stats
+		 * and jump to the 'action' part of
+		 * the parent rule by setting
+		 * f, cmd, l and clearing cmdlen.
+		 */
+		IPFW_INC_DYN_COUNTER(q, pktlen);
+		/* XXX we would like to have f_pos
+		 * readily accessible in the dynamic
+	         * rule, instead of having to
+		 * lookup q->rule.
+		 */
+		f = q->rule;
+		*f_pos = ipfw_find_rule(chain,
+			f->rulenum, f->id);
+		cmd = ACTION_PTR(f);
+		*l = f->cmd_len - f->act_ofs;
+		ipfw_dyn_unlock(q);
+		*cmdlen = 0;
+		*match = 1;
+		return;
+	}
+	/*
+	 * Dynamic entry not found. If CHECK_STATE,
+	 * skip to next rule, if PROBE_STATE just
+	 * ignore and continue with next opcode.
+	 */
+	if (cmd->opcode == O_CHECK_STATE)
+		*l = 0;	/* exit inner loop */
+	*match = 1;
 }
 
 inline void
-rule_accept(retval, l, done)
+rule_accept(int *retval, int *l, int *done)
 {
+	*retval = 0;	/* accept */
+	*l = 0;		/* exit inner loop */
+	*done = 1;	/* exit outer loop */
 }
 
 inline void
-rule_queue(args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, retval, l, done)
+rule_queue(struct ip_fw_args *args, int f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, int *retval, int *l, int *done)
 {
+	set_match(args, f_pos, chain);
+	args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
+	if (cmd->opcode == O_PIPE)
+		args->rule.info |= IPFW_IS_PIPE;
+	if (V_fw_one_pass)
+		args->rule.info |= IPFW_ONEPASS;
+	*retval = IP_FW_DUMMYNET;
+	*l = 0;          /* exit inner loop */
+	*done = 1;       /* exit outer loop */
 }
 
 inline void
-rule_tee(args, l, done, retval, ipfw_insn *cmd, struct ip_fw_args *args, f_pos, struct ip_fw_chain *chain)
+rule_tee(int *l, int *done, int *retval, ipfw_insn *cmd, struct ip_fw_args *args, int f_pos, struct ip_fw_chain *chain)
 {
+	if (args->eh) /* not on layer 2 */
+	    return;
+	/* otherwise this is terminal */
+	*l = 0;		/* exit inner loop */
+	*done = 1;	/* exit outer loop */
+	*retval = (cmd->opcode == O_DIVERT) ?
+		IP_FW_DIVERT : IP_FW_TEE;
+	set_match(args, f_pos, chain);
+	args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
 }
 
 inline void
-rule_count(l, f, pktlen)
+rule_count(int *l, struct ip_fw *f, int pktlen)
 {
+	IPFW_INC_RULE_COUNTER(f, pktlen);
+	*l = 0;		/* exit inner loop */
 }
 
 inline void
-rule_skipto(int *match, f, f_pos, pktlen, struct ip_fw_chain *chain, ipfw_insn *cmd, uint32_t *tablearg, l, ipfw_insn *cmd, int *cmdlen, skip_or)
+rule_skipto(int *match, int *l, ipfw_insn *cmd, int *cmdlen, int *skip_or, int *f_pos, struct ip_fw *f, int pktlen, struct ip_fw_chain *chain, ipfw_insn *cmd, uint32_t tablearg)
 {
+    IPFW_INC_RULE_COUNTER(f, pktlen);
+    *f_pos = jump_fast(chain, f, cmd->arg1, tablearg, 0);
+    /*
+     * Skip disabled rules, and re-enter
+     * the inner loop with the correct
+     * f_pos, f, l and cmd.
+     * Also clear cmdlen and skip_or
+     */
+    for (; f_pos < chain->n_rules - 1 &&
+	    (V_set_disable &
+	     (1 << chain->map[f_pos]->set));
+	    f_pos++)
+	;
+    /* Re-enter the inner loop at the skipto rule. */
+    f = chain->map[f_pos];
+    *l = f->cmd_len;
+    cmd = f->cmd;
+    *match = 1;
+    *cmdlen = 0;
+    *skip_or = 0;
 }
 
 inline void
-rule_callreturn(ipfw_insn *cmd, int *cmdlen, struct mbuf *m, l, f, pktlen, uint32_t *tablearg, jmpto, f_pos, struct ip_fw_chain *chain, skip_or)
+rule_callreturn(ipfw_insn *cmd, int *cmdlen, struct mbuf *m, int *l, struct ip_fw *f, int pktlen, uint32_t *tablearg, jmpto, f_pos, struct ip_fw_chain *chain, int *skip_or)
 {
 }
 
@@ -862,42 +957,42 @@
 
 
 inline void
-rule_deny(l, done, retval)
+rule_deny(int *l, int *done, int *retval)
 {
 }
 
 inline void
-rule_forward_ip(args, q, dyn_dir, ipfw_insn *cmd, sa, retval, l, done)
+rule_forward_ip(args, q, dyn_dir, ipfw_insn *cmd, sa, int *retval, int *l, int *done)
 {
 }
 
 #ifdef INET6
 inline void
-rule_forward_ip6(args, q, f, dun_dir, ipfw_insn *cmd, struct ip_fw_args *args, retval, l, done)
+rule_forward_ip6(args, q, struct ip_fw *f, dun_dir, ipfw_insn *cmd, struct ip_fw_args *args, int *retval, int *l, int *done)
 {
 }
 #endif /* INET6 */
 
 inline void
-rule_ngtee(args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, V_fw_one_pass, retval, l, done)
+rule_ngtee(args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, V_fw_one_pass, int *retval, int *l, int *done)
 {
 }
 
 inline void
-rule_setfib(f, pktlen, ipfw_insn *cmd, rt_numfibs, struct mbuf *m, struct ip_fw_args *args, l)
+rule_setfib(struct ip_fw *f, int pktlen, ipfw_insn *cmd, rt_numfibs, struct mbuf *m, struct ip_fw_args *args, int *l)
 {
 }
 
 inline void
-rule_setdscp(ipfw_insn *cmd, l, int is_ipv4 a, int is_ipv6 f, pktlen)
+rule_setdscp(ipfw_insn *cmd, int *l, int is_ipv4 a, int is_ipv6 f, int pktlen)
 {
 }
 
 inline void
-rule_nat(l, done, retval, struct ip_fw_args *args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, struct ip_fw_chain *chain)
+rule_nat(int *l, int *done, int *retval, struct ip_fw_args *args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, struct ip_fw_chain *chain)
 {
 }
 
-inlinue void rule_reass(f, pktlen, l, ip_off, struct ip *ip, struct ip_fw_args *args, struct mbuf *m, retval, done)
+inlinue void rule_reass(struct ip_fw *f, int pktlen, int *l, ip_off, struct ip *ip, struct ip_fw_args *args, struct mbuf *m, int *retval, int *done)
 {
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406120840.s5C8edED014071>