socsvn commit: r272215 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
dpl at FreeBSD.org
dpl at FreeBSD.org
Mon Aug 11 16:20:56 UTC 2014
Author: dpl
Date: Mon Aug 11 16:20:55 2014
New Revision: 272215
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272215
Log:
Setting up the JIT compilation env.
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 Mon Aug 11 16:05:22 2014 (r272214)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Mon Aug 11 16:20:55 2014 (r272215)
@@ -35,7 +35,6 @@
using namespace llvm;
class ipfwJIT {
- private:
Module *mod;
Function *func;
LLVMContext con;
@@ -47,16 +46,80 @@
Type *int8Ty;
Type *int16Ty;
Type *int32Ty;
+ PointerType *int8PtrTy;
// JIT Compiled Vars
+ // Loop control.
Value *match;
Value *l;
Value *done;
Value *f_pos;
Value *retval;
- // Functions used by our JITed code.
+ // Packet matching variables.
+ Value *mbuf;
+ Value *ip;
+ Value *ucred;
+ Value *ucred_lookup;
+ Value *oif;
+ Value *hlen; //unsigned
+ Value *offset; //unsigned
+ Value *ip6f_mf; //unsigned
+
+ // Local copies of vars.
+ // On optimization, unused ones will not be included.
+ Value *proto; //unsigned
+ Value *src_port; //unsigned
+ Value *dst_port; //unsigned
+ Value *src_ip;
+ Value *dest_ip;
+ Value *iplen; //unsigned
+ Value *pktlen;
+ Value *etype; //unsigned
+ Value *dyn_dir;
+ Value *q;
+ Value *ulp;
+
+ Value *is_ipv4;
+ Value *is_ipv6;
+ Value *icmp6_type; //unsigned
+ Value *ext_hd; //unsigned
+
+ // This sets up some vars, at star time.
+ Function *look_pkt;
+
+ // Auxiliary functions used by our JITed code.
+ Function *is_icmp_query;
+ Function *flags_match;
+ Function *ipopts_match;
+ Function *tcpopts_match;
Function *iface_match;
+ Function *verify_path;
+#ifdef INET6
+ Function *icmp6type_match;
+ Function *search_ip6_addr_net;
+ Function *flow6id_match;
+ Function *verify_path6;
+ Function *is_icmp6_query;
+ Function *send_reject6;
+#endif /* INET6 */
+ Function *send_reject;
+ Function *check_uidgid;
+ Function *set_match;
+ Function *jump_fast;
+
+ // Used structs
+ StructType *ifnetTy;
+ StructType *in_addrTy;
+ StructType *ipTy;
+ StructType *ip_fw_argsTy;
+ StructType *ip_fw_chainTy;
+ StructType *ip_fwTy;
+ StructType *ip_fw_insnTy;
+ StructType *ipfw_dyn_ruleTy;
+ StructType *ipfw_insn_ifTy;
+ StructType *mbufTy;
+ StructType *ucredTy;
// Load the bc for JIT compilation.
Module *loadbc(std::string name)
@@ -79,32 +142,131 @@
// Create the needed variables to perform pkt filtering.
int
- setEnv()
+ setEnv(struct ip_fw_args *args, struct ip_fw_chain *chain)
{
// Get Type objects
int8Ty = Type::getInt8Ty(con);
int16Ty = Type::getInt16Ty(con);
int32Ty = Type::getInt32Ty(con);
+ int8PtrTy = PointerType::getUnqual(int8Ty);
// Get StrucType from bitcode.
+ ipfw_dyn_ruleTy = mod->getTypeByName("ipfw_dyn_rule");
+ ifnetTy = mod->getTypeByName("ifnet");
+ in_addrTy = mod->getTypeByName("in_addr");
+ ipTy = mod->getTypeByName("ip");
+ ip_fw_argsTy = mod->getTypeByName("ip_fw_args");
+ ip_fw_chainTy = mod->getTypeByName("ip_fw_chain");
+ ip_fwTy = mod->getTypeByName("ip_fw");
+ ip_fw_insnTy = mod->getTypeByName("ip_fw_insn");
+ ipfw_insn_ifTy = mod->getTypeByName("ipfw_insn_if");
+ mbufTy = mod->getTypeByName("mbuf");
+#ifndef __FreeBSD__
+ ucredTy = mod->getTypeByName("bsd_ucred");
+#else
+ ucredTy = mod->getTypeByName("ucred");
+#endif /* __FreeBSD__ */
- // Store vars.
+ // Allocate vars.
match = irb.CreateAlloca(int32Ty);
l = irb.CreateAlloca(int32Ty);
done = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), done);
f_pos = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), f_pos);
retval = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), retval);
+
+ mbuf = irb.CreateAlloca(mbufTy); // Init: args->m
+ // ip = mtod(m, struct ip *)
+ // #define mtod(m, t) ((t)((m)->m_data))
+ ip = irb.CreateAlloca(ipTy);
+
+ ucred = irb.CreateAlloca(ucredTy); // Init: NULL if type ucred.
+#ifdef __FreeBSD__
+ irb.CreateStore(ConstantPointerNull::get(null), ucred);
+#endif
+
+ ucred_lookup = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), ucred_lookup);
+
+ oif = irb.CreateAlloca(ifnetTy); // Init: args->oif
+
+ hlen = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), hlen);
+
+ offset = irb.CreateAlloca(int16Ty);
+ irb.CreateStore(ConstantInt::get(int16Ty, 0), offset);
+
+ ip6f_mf = irb.CreateAlloca(int16Ty);
+ irb.CreateStore(ConstantInt::get(int16Ty, 0), ip6f_mf);
+
+ proto = irb.CreateAlloca(int8Ty);
+
+ src_port = irb.CreateAlloca(int16Ty);
+ irb.CreateStore(ConstantInt::get(int16Ty, 0), src_port);
+ dst_port = irb.CreateAlloca(int16Ty);
+ irb.CreateStore(ConstantInt::get(int16Ty, 0), dst_port);
+
+ src_ip = irb.CreateAlloca(in_addrTy);
+ dest_ip = irb.CreateAlloca(in_addrTy);
+
+ iplen = irb.CreateAlloca(int16Ty);
+ irb.CreateStore(ConstantInt::get(int16Ty, 0), iplen);
- // Create needed GlobalVariables.
+ pktlen = irb.CreateAlloca(int32Ty);
+
+ etype = irb.CreateAlloca(int16Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), etype);
+
+ dyn_dir = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, MATCH_UNKNOWN), dyn_dir);
+
+ q = irb.CreateAlloca(ipfw_dyn_ruleTy);
+ irb.CreateStore(ConstantPointerNull::get(null), q);
+
+ // There are no (void *), we use i8*
+ ulp = irb.CreateAlloca(int8PtrTy); //Init: NULL
+ irb.CreateStore(ConstantPointerNull::get(null), ulp);
+
+ is_ipv4 = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), is_ipv4);
+ is_ipv6 = irb.CreateAlloca(int32Ty);
+ irb.CreateStore(ConstantInt::get(int32Ty, 0), is_ipv6);
+ icmp6_type = irb.CreateAlloca(int8Ty);
+ irb.CreateStore(ConstantInt::get(int8Ty, 0), icmp6_type);
+ ext_hd = irb.CreateAlloca(int16Ty);
+ irb.CreateStore(ConstantInt::get(int16Ty, 0), ext_hd);
// Get Function defs from bitcode.
+ // All of them are auxiliary functions.
+ look_pkt = mod->getFunction("look_pkt");
+ is_icmp_query = mod->getFunction("is_icmp_query");
+ flags_match = mod->getFunction("flags_match");
+ ipopts_match = mod->getFunction("ipopts_match");
+ tcpopts_match = mod->getFunction("tcpopts_match");
iface_match = mod->getFunction("iface_match");
+ verify_path = mod->getFunction("verify_path");
+
+#ifdef INET6
+ icmp6type_match = mod->getFunction("icmp6type_match");
+ search_ip6_addr_net = mod->getFunction("search_ip6_addr_net");
+ flow6id_match = mod->getFunction("flow6id_match");
+ verify_path6 = mod->getFunction("verify_path6");
+ is_icmp6_query = mod->getFunction("is_icmp6_query");
+ send_reject6 = mod->getFunction("send_reject6");
+#endif /* INET6 */
+
+ send_reject = mod->getFunction("send_reject");
+ check_uidgid = mod->getFunction("check_uidgid");
+ set_match = mod->getFunction("set_match");
+ jump_fast = mod->getFunction("jump_fast");
return (0);
}
public:
- ipfwJIT(): irb(con)
+ ipfwJIT(struct ip_fw_args *args, struct ip_fw_chain *chain): irb(con)
{
// Create the module and load the code.
mod = loadbc("ip_fw_rules.bc");
@@ -118,8 +280,8 @@
// Set the IRBuilder to insert instructions after the basic block.
irb.SetInsertPoint(entry);
// Get struct types, and store vars
- setEnv();
- // From on on, it's just a matter of emitting the code for each rule/action.
+ setEnv(args, chain);
+ // Emitting the code for each rule/action now->
}
~ipfwJIT()
{
@@ -212,15 +374,15 @@
extern "C" funcptr
compile_code(struct ip_fw_args *args, struct ip_fw_chain *chain)
{
- int res;
- ipfwJIT comp;
+ ipfwJIT comp(args, chain);
+ int res;
int f_pos = 0;
- int retval = 0;
- // Iterate through the rules.
+ // Fill up needed variables type.
+ comp.emit_lookpkt();
- int done = 0; /* flag to exit the outer loop */
+ // Iterate through the rules.
int pktlen = args->m->m_pkthdr.len;
// For all the number of rules.
More information about the svn-soc-all
mailing list