socsvn commit: r272412 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
dpl at FreeBSD.org
dpl at FreeBSD.org
Thu Aug 14 16:23:58 UTC 2014
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());
More information about the svn-soc-all
mailing list