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>