Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Aug 2014 16:23:57 GMT
From:      dpl@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r272412 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
Message-ID:  <201408141623.s7EGNvHZ024761@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dpl
Date: Thu Aug 14 16:23:57 2014
New Revision: 272412
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272412

Log:
  Added basic code to start emitting parts of the control flow.

Modified:
  soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc

Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc
==============================================================================
--- soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc	Thu Aug 14 15:46:15 2014	(r272411)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc	Thu Aug 14 16:23:57 2014	(r272412)
@@ -56,7 +56,9 @@
 	BasicBlock *entry;
 	BasicBlock *pullup_failed;
 	BasicBlock *startrules;
-	BasicBlock *check_tag;
+	BasicBlock *end;
+	// This BB is the next emitted rule, always.
+	BasicBlock *next;
 
 	// JIT Compiled Vars
 	// These are the function arguments.
@@ -361,7 +363,6 @@
 		// 		printf("ipfw: pullup failed\n");
 		// 	return (IP_FW_DENY);
 
-		irb.SetInsertPoint(pullup_failed);
 		is_verbose = mod->getGlobalVariable("fw_verbose");
 		str = irb.CreateGlobalString("ipfw: pullup failed\n");
 
@@ -399,8 +400,6 @@
 		// 	f_pos = 0;
 		// }
 
-		irb.SetInsertPoint(check_tag);
-
 		// if (args->rule.slot)
 		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateInBoundsGEP(argsptr, {ConstantInt::get(int32Ty, 4),ConstantInt::get(int32Ty, 0)}), ConstantInt::get(int32Ty, 0)), nottagged, tagged);
 		// if (args->rule.chain_id == chain->id)
@@ -417,7 +416,7 @@
 		irb.CreateStore(irb.CreateCall3(ipfw_find_rule, chainptr, irb.CreateInBoundsGEP(argsptr, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 1)}), irb.CreateInBoundsGEP(argsptr, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 2)})), f_pos);
 
 		// Branch to nottagged because it
-		// only finishes the check_tag BasicBlock.
+		// only finishes the entry BasicBlock.
 		irb.CreateBr(nottagged);
 
 		// else f_pos = 0;
@@ -436,17 +435,26 @@
 		func->setLinkage(GlobalValue::ExternalLinkage);
 
 		// Create statics BasicBlocks.
+		// The entry basic block contains all the initialization 
+		// and allocation of resources, and a basic check done 
+		// before start emmiting the rules code.
 		entry = BasicBlock::Create(con, "entry", func);
+		// This is equivalent to the pullup_failed tag.
 		pullup_failed = BasicBlock::Create(con, "pullup_failed", func);
-		check_tag = BasicBlock::Create(con, "check_tag", func);
+		// This will be the first BasicBlock to store our emmited code.
 		startrules = BasicBlock::Create(con, "startrules", func);
-
-		emit_pullup_failed();
-		emit_check_tag();
+		// This will be executed at the end of ipfw_chk_jit().
+		end = BasicBlock::Create(con, "end", func);
 
 		// Get struct types, and store vars
+		irb.SetInsertPoint(entry);
 		setEnv();
 		allocaAndInit(args, chain);
+
+		emit_check_tag();
+
+		irb.SetInsertPoint(pullup_failed);
+		emit_pullup_failed();
 	}
 	~ipfwJIT()
 	{
@@ -468,13 +476,61 @@
 	}
 
 	// Call the function that fills in some vars.
-	int
+	void
 	emit_lookpkt()
 	{
 		// If it returns one, goto pullup_failed.
 		// Else, goto starrules.
 		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateCall(inspect_pkt, {argsptr, ip, m, src_ip, dst_ip, src_port, dst_port, etype, ext_hd, iplen, pktlen, is_ipv4, is_ipv6, hlen, proto, icmp6_type, ip6f_mf, offset, ulp}), ConstantInt::get(int32Ty, 1)), pullup_failed, startrules);
-		return (0);
+		return;
+	}
+
+	// We get here ar the end of switch() on opcodes.
+	// XXX
+	void
+	emit_end_switch()
+	{
+		// /* if we get here with l=0, then match is irrelevant. */
+		// if (cmd->len & F_NOT)
+		// 	match = !match;
+
+		// if (match) {
+		// 	if (cmd->len & F_OR)
+		// 		skip_or = 1;
+		// } else {
+		// 	if (!(cmd->len & F_OR)) /* not an OR block, */
+		// 		break;		/* try next rule    */
+		// }
+	}
+
+	// This code gets executed at the end of inner loop.
+	// In this context, break means goto end, else continue loop.
+	void
+	emit_end_opcodes()
+	{
+		// if (done)
+		//	break;
+		irb.CreateCondBr(irb.CreateCmpNE(done, ConstantInt::get(int32Ty, 0)), end, next);
+	}
+
+	// This will emit some code executed at the end.
+	// And set up basic blocks, if necessary.
+	// XXX
+	void
+	emit_end()
+	{
+		// if (done) {
+		//		struct ip_fw *rule = chain->map[f_pos];
+		//		/* Update statistics */
+		//		(rule)->pcnt++;
+		//		(rule)->bcnt += pktlen;
+		//		(rule)->timestamp = time_uptime;
+		// } else {
+		//		retval = IP_FW_DENY;
+		//		printf("ipfw: ouch!, skip past end of rules, denying packet\n");
+		// }
+
+		irb.SetInsertPoint(end);
 	}
 
 	// Rules
@@ -523,6 +579,7 @@
 	int pktlen = args->m->m_pkthdr.len;
 
 	// For all the number of rules.
+	// It seems that we can create a control flow based on this.
 	for (; f_pos < chain->n_rules; f_pos++) {
 		ipfw_insn *cmd;
 		int l, cmdlen, skip_or; /* skip rest of OR block */
@@ -916,9 +973,13 @@
 			default:
 				panic("-- unknown opcode %d\n", cmd->opcode);
 			} /* end of switch() on opcodes */
+			comp.emit_end_switch();
 		}	/* end of inner loop, scan opcodes */
+		comp.emit_end_opcodes();
 	}		/* end of outer for, scan rules */
 
+	comp.emit_end();
+
 	// Once we're done iterating through the rules, return the pointer.
 	comp.optimize();
 	return (comp.getFuncPtr());



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