Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Aug 2014 16:20:56 GMT
From:      dpl@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r272215 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
Message-ID:  <201408111620.s7BGKuoO027791@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.



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