From owner-svn-soc-all@FreeBSD.ORG Mon Aug 11 16:20:56 2014 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A22296B7 for ; Mon, 11 Aug 2014 16:20:56 +0000 (UTC) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 82ED82EF5 for ; Mon, 11 Aug 2014 16:20:56 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7BGKu4x027793 for ; Mon, 11 Aug 2014 16:20:56 GMT (envelope-from dpl@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id s7BGKuoO027791 for svn-soc-all@FreeBSD.org; Mon, 11 Aug 2014 16:20:56 GMT (envelope-from dpl@FreeBSD.org) Date: Mon, 11 Aug 2014 16:20:56 GMT Message-Id: <201408111620.s7BGKuoO027791@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to dpl@FreeBSD.org using -f From: dpl@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272215 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Aug 2014 16:20:56 -0000 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.