socsvn commit: r274302 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw

dpl at FreeBSD.org dpl at FreeBSD.org
Thu Sep 18 13:28:48 UTC 2014


Author: dpl
Date: Thu Sep 18 13:28:47 2014
New Revision: 274302
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=274302

Log:
  Added Function objects to get from the bitcode.

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 Sep 18 13:27:30 2014	(r274301)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc	Thu Sep 18 13:28:47 2014	(r274302)
@@ -86,7 +86,7 @@
 	Value *FPos;
 	Value *Retval;
 	Value *Cmd;
-	Value *CmdLen;
+	Value *Cmdlen;
 	Value *Tablearg;
 	Value *SkipOr;
 	Value *F;
@@ -143,9 +143,100 @@
 	Function *SetMatch;
 	Function *JumpFast;
 
+	// External functions
 	Function *PrintfFunc;
 	Function *IpfwFindRule;
 
+	// Rules
+	Function *RuleNop;
+	Function *RuleForwardMac;
+	Function *RuleJail;
+	Function *RuleRecv;
+	Function *RuleXmit;
+	Function *RuleVia;
+	Function *RuleMacaddr2;
+	Function *RuleMacType;
+	Function *RuleFrag;
+	Function *RuleIn;
+	Function *RuleLayer2;
+	Function *RuleDiverted;
+	Function *RuleProto;
+	Function *RuleIpSrc;
+	Function *RuleIpDstLookup;
+	Function *RuleIpDstMask;
+	Function *RuleIpSrcMe;
+#ifdef INET6
+	Function *RuleIp6SrcMe;
+#endif
+	Function *RuleIpSrcSet;
+	Function *RuleIpDst;
+	Function *RuleIpDstMe;
+#ifdef INET6
+	Function *RuleIp6DstMe;
+#endif
+	Function *RuleIpDstport;
+	Function *RuleIcmptype;
+#ifdef INET6
+	Function *RuleIcmp6type;
+#endif
+	Function *RuleIpopt;
+	Function *RuleIpver;
+	Function *RuleIpttl;
+	Function *RuleIpprecedence;
+	Function *RuleIptos;
+	Function *RuleDscp;
+	Function *RuleTcpdatalen;
+	Function *RuleTcpflags;
+	Function *RuleTcpopts;
+	Function *RuleTcpseq;
+	Function *RuleTcpack;
+	Function *RuleTcpwin;
+	Function *RuleEstab;
+	Function *RuleAltq;
+	Function *RuleLog;
+	Function *RuleProb;
+	Function *RuleVerrevpath;
+	Function *RuleVersrcreach;
+	Function *RuleAntispoof;
+#ifdef IPSEC
+		Function *RuleIpsec;
+#endif
+#ifdef INET6
+		Function *RuleIp6Src;
+		Function *RuleIp6Dst;
+		Function *RuleIp6DstMask;
+		Function *RuleFlow6id;
+		Function *RuleExtHdr;
+		Function *RuleIp6;
+#endif
+	Function *RuleIp4;
+	Function *RuleTag;
+	Function *RuleFib;
+	Function *RuleSockarg;
+	Function *RuleTagged;
+	Function *RuleKeepState;
+	Function *RuleCheckState;
+	Function *RuleAccept;
+	Function *RuleQueue;
+	Function *RuleTee;
+	Function *RuleCount;
+	Function *RuleSkipto;
+	Function *RuleCallreturn;
+	Function *RuleReject;
+#ifdef INET6
+		Function *RuleUnreach6;
+#endif
+	Function *RuleDeny;
+	Function *RuleForwardIp;
+#ifdef INET6
+	Function *RuleForwardIp6;
+#endif
+	Function *RuleNgtee;
+	Function *RuleSetfib;
+	Function *RuleSetdscp;
+	Function *RuleNat;
+	Function *RuleReass;
+
 	// Used structs.
 	StructType *IfnetTy;
 	StructType *In_addrTy;
@@ -341,6 +432,257 @@
 		IpfwFindRule = mod->getFunction("ipfw_find_rule");
 		if (IpfwFindRule == NULL)
 			err(1, "bitcode fault: ipfw_find_rule");
+
+		// Load the rules
+		RuleNop = mod->getFunction("rule_nop");
+		if (RuleNop  == NULL)
+			err(1, "bitcode fault: RuleNop ");
+		RuleForwardMac = mod->getFunction("rule_forward_mac");
+		if (RuleForwardMac  == NULL)
+			err(1, "bitcode fault: RuleForwardMac ");
+		RuleJail = mod->getFunction("rule_jail");
+		if (RuleJail  == NULL)
+			err(1, "bitcode fault: RuleJail ");
+		RuleRecv = mod->getFunction("rule_recv");
+		if (RuleRecv  == NULL)
+			err(1, "bitcode fault: RuleRecv ");
+		RuleXmit = mod->getFunction("rule_xmit");
+		if (RuleXmit  == NULL)
+			err(1, "bitcode fault: RuleXmit ");
+		RuleVia = mod->getFunction("rule_via");
+		if (RuleVia  == NULL)
+			err(1, "bitcode fault: RuleVia ");
+		RuleMacaddr2 = mod->getFunction("rule_macaddr2");
+		if (RuleMacaddr2  == NULL)
+			err(1, "bitcode fault: RuleMacaddr2 ");
+		RuleMacType = mod->getFunction("rule_mac_type");
+		if (RuleMacType  == NULL)
+			err(1, "bitcode fault: RuleMacType ");
+		RuleFrag = mod->getFunction("rule_frag");
+		if (RuleFrag  == NULL)
+			err(1, "bitcode fault: RuleFrag ");
+		RuleIn = mod->getFunction("rule_in");
+		if (RuleIn  == NULL)
+			err(1, "bitcode fault: RuleIn ");
+		RuleLayer2 = mod->getFunction("rule_layer2");
+		if (RuleLayer2  == NULL)
+			err(1, "bitcode fault: RuleLayer2 ");
+		RuleDiverted = mod->getFunction("rule_diverted");
+		if (RuleDiverted  == NULL)
+			err(1, "bitcode fault: RuleDiverted ");
+		RuleProto = mod->getFunction("rule_proto");
+		if (RuleProto  == NULL)
+			err(1, "bitcode fault: RuleProto ");
+		RuleIpSrc = mod->getFunction("rule_ip_src");
+		if (RuleIpSrc  == NULL)
+			err(1, "bitcode fault: RuleIpSrc ");
+		RuleIpDstLookup = mod->getFunction("rule_ip_dst_lookup");
+		if (RuleIpDstLookup  == NULL)
+			err(1, "bitcode fault: RuleIpDstLookup ");
+		RuleIpDstMask = mod->getFunction("rule_ip_dst_mask");
+		if (RuleIpDstMask  == NULL)
+			err(1, "bitcode fault: RuleIpDstMask ");
+		RuleIpSrcMe = mod->getFunction("rule_ip_src_me");
+		if (RuleIpSrcMe  == NULL)
+			err(1, "bitcode fault: RuleIpSrcMe ");
+
+#ifdef INET6
+		RuleIp6SrcMe = mod->getFunction("rule_ip6_src_me");
+		if (RuleIp6SrcMe  == NULL)
+			err(1, "bitcode fault: RuleIp6SrcMe ");
+#endif
+
+		RuleIpSrcSet = mod->getFunction("rule_ip_src_set");
+		if (RuleIpSrcSet  == NULL)
+			err(1, "bitcode fault: RuleIpSrcSet ");
+		RuleIpDst = mod->getFunction("rule_ip_dst");
+		if (RuleIpDst  == NULL)
+			err(1, "bitcode fault: RuleIpDst ");
+		RuleIpDstMe = mod->getFunction("rule_ip_dst_me");
+		if (RuleIpDstMe  == NULL)
+			err(1, "bitcode fault: RuleIpDstMe ");
+
+#ifdef INET6
+		RuleIp6DstMe = mod->getFunction("rule_ip6_dst_me");
+		if (RuleIp6DstMe  == NULL)
+			err(1, "bitcode fault: RuleIp6DstMe ");
+#endif
+
+		RuleIpDstport = mod->getFunction("rule_ip_dstport");
+		if (RuleIpDstport  == NULL)
+			err(1, "bitcode fault: RuleIpDstport ");
+		RuleIcmptype = mod->getFunction("rule_icmptype");
+		if (RuleIcmptype  == NULL)
+			err(1, "bitcode fault: RuleIcmptype ");
+
+#ifdef INET6
+		RuleIcmp6type = mod->getFunction("rule_icmp6type");
+		if (RuleIcmp6type  == NULL)
+			err(1, "bitcode fault: RuleIcmp6type ");
+#endif
+
+		RuleIpopt = mod->getFunction("rule_ipopt");
+		if (RuleIpopt  == NULL)
+			err(1, "bitcode fault: RuleIpopt ");
+		RuleIpver = mod->getFunction("rule_ipver");
+		if (RuleIpver  == NULL)
+			err(1, "bitcode fault: RuleIpver ");
+		RuleIpttl = mod->getFunction("rule_ipttl");
+		if (RuleIpttl  == NULL)
+			err(1, "bitcode fault: RuleIpttl ");
+		RuleIpprecedence = mod->getFunction("rule_ipprecedence");
+		if (RuleIpprecedence  == NULL)
+			err(1, "bitcode fault: RuleIpprecedence ");
+		RuleIptos = mod->getFunction("rule_iptos");
+		if (RuleIptos  == NULL)
+			err(1, "bitcode fault: RuleIptos ");
+		RuleDscp = mod->getFunction("rule_dscp");
+		if (RuleDscp  == NULL)
+			err(1, "bitcode fault: RuleDscp ");
+		RuleTcpdatalen = mod->getFunction("rule_tcpdatalen");
+		if (RuleTcpdatalen  == NULL)
+			err(1, "bitcode fault: RuleTcpdatalen ");
+		RuleTcpflags = mod->getFunction("rule_tcpflags");
+		if (RuleTcpflags  == NULL)
+			err(1, "bitcode fault: RuleTcpflags ");
+		RuleTcpopts = mod->getFunction("rule_tcpopts");
+		if (RuleTcpopts  == NULL)
+			err(1, "bitcode fault: RuleTcpopts ");
+		RuleTcpseq = mod->getFunction("rule_tcpseq");
+		if (RuleTcpseq  == NULL)
+			err(1, "bitcode fault: RuleTcpseq ");
+		RuleTcpack = mod->getFunction("rule_tcpack");
+		if (RuleTcpack  == NULL)
+			err(1, "bitcode fault: RuleTcpack ");
+		RuleTcpwin = mod->getFunction("rule_tcpwin");
+		if (RuleTcpwin  == NULL)
+			err(1, "bitcode fault: RuleTcpwin ");
+		RuleEstab = mod->getFunction("rule_estab");
+		if (RuleEstab  == NULL)
+			err(1, "bitcode fault: RuleEstab ");
+		RuleAltq = mod->getFunction("rule_altq");
+		if (RuleAltq  == NULL)
+			err(1, "bitcode fault: RuleAltq ");
+		RuleLog = mod->getFunction("rule_log");
+		if (RuleLog  == NULL)
+			err(1, "bitcode fault: RuleLog ");
+		RuleProb = mod->getFunction("rule_prob");
+		if (RuleProb  == NULL)
+			err(1, "bitcode fault: RuleProb ");
+		RuleVerrevpath = mod->getFunction("rule_verrevpath");
+		if (RuleVerrevpath  == NULL)
+			err(1, "bitcode fault: RuleVerrevpath ");
+		RuleVersrcreach = mod->getFunction("rule_versrcreach");
+		if (RuleVersrcreach  == NULL)
+			err(1, "bitcode fault: RuleVersrcreach ");
+		RuleAntispoof = mod->getFunction("rule_antispoof");
+		if (RuleAntispoof  == NULL)
+			err(1, "bitcode fault: RuleAntispoof ");
+
+#ifdef IPSEC
+		RuleIpsec = mod->getFunction("rule_ipsec");
+		if (RuleIpsec  == NULL)
+			err(1, "bitcode fault: RuleIpsec ");
+#endif
+
+#ifdef INET6
+		RuleIp6Src = mod->getFunction("rule_ip6_src");
+		if (RuleIp6Src  == NULL)
+			err(1, "bitcode fault: RuleIp6Src ");
+		RuleIp6Dst = mod->getFunction("rule_ip6_dst");
+		if (RuleIp6Dst  == NULL)
+			err(1, "bitcode fault: RuleIp6Dst ");
+		RuleIp6DstMask = mod->getFunction("rule_ip6_dst_mask");
+		if (RuleIp6DstMask  == NULL)
+			err(1, "bitcode fault: RuleIp6DstMask ");
+		RuleFlow6id = mod->getFunction("rule_flow6id");
+		if (RuleFlow6id  == NULL)
+			err(1, "bitcode fault: RuleFlow6id ");
+		RuleExtHdr = mod->getFunction("rule_ext_hdr");
+		if (RuleExtHdr  == NULL)
+			err(1, "bitcode fault: RuleExtHdr ");
+		RuleIp6 = mod->getFunction("rule_ip6");
+		if (RuleIp6  == NULL)
+			err(1, "bitcode fault: RuleIp6 ");
+#endif
+
+		RuleIp4 = mod->getFunction("rule_ip4");
+		if (RuleIp4  == NULL)
+			err(1, "bitcode fault: RuleIp4 ");
+		RuleTag = mod->getFunction("rule_tag");
+		if (RuleTag  == NULL)
+			err(1, "bitcode fault: RuleTag ");
+		RuleFib = mod->getFunction("rule_fib");
+		if (RuleFib  == NULL)
+			err(1, "bitcode fault: RuleFib ");
+		RuleSockarg = mod->getFunction("rule_sockarg");
+		if (RuleSockarg  == NULL)
+			err(1, "bitcode fault: RuleSockarg ");
+		RuleTagged = mod->getFunction("rule_tagged");
+		if (RuleTagged  == NULL)
+			err(1, "bitcode fault: RuleTagged ");
+		RuleKeepState = mod->getFunction("rule_keep_state");
+		if (RuleKeepState  == NULL)
+			err(1, "bitcode fault: RuleKeepState ");
+		RuleCheckState = mod->getFunction("rule_check_state");
+		if (RuleCheckState  == NULL)
+			err(1, "bitcode fault: RuleCheckState ");
+		RuleAccept = mod->getFunction("rule_accept");
+		if (RuleAccept  == NULL)
+			err(1, "bitcode fault: RuleAccept ");
+		RuleQueue = mod->getFunction("rule_queue");
+		if (RuleQueue  == NULL)
+			err(1, "bitcode fault: RuleQueue ");
+		RuleTee = mod->getFunction("rule_tee");
+		if (RuleTee  == NULL)
+			err(1, "bitcode fault: RuleTee ");
+		RuleCount = mod->getFunction("rule_count");
+		if (RuleCount  == NULL)
+			err(1, "bitcode fault: RuleCount ");
+		RuleSkipto = mod->getFunction("rule_skipto");
+		if (RuleSkipto  == NULL)
+			err(1, "bitcode fault: RuleSkipto ");
+		RuleCallreturn = mod->getFunction("rule_callreturn");
+		if (RuleCallreturn  == NULL)
+			err(1, "bitcode fault: RuleCallreturn ");
+		RuleReject = mod->getFunction("rule_reject");
+		if (RuleReject  == NULL)
+			err(1, "bitcode fault: RuleReject ");
+
+#ifdef INET6
+		RuleUnreach6 = mod->getFunction("rule_unreach6");
+		if (RuleUnreach6  == NULL)
+			err(1, "bitcode fault: RuleUnreach6 ");
+#endif
+
+		RuleDeny = mod->getFunction("rule_deny");
+		if (RuleDeny  == NULL)
+			err(1, "bitcode fault: RuleDeny ");
+		RuleForwardIp = mod->getFunction("rule_forward_ip");
+		if (RuleForwardIp  == NULL)
+			err(1, "bitcode fault: RuleForwardIp ");
+
+#ifdef INET6
+		RuleForwardIp6 = mod->getFunction("rule_forward_ip6");
+		if (RuleForwardIp6  == NULL)
+			err(1, "bitcode fault: RuleForwardIp6 ");
+#endif
+
+		RuleNgtee = mod->getFunction("rule_ngtee");
+		if (RuleNgtee  == NULL)
+			err(1, "bitcode fault: RuleNgtee ");
+		RuleSetfib = mod->getFunction("rule_setfib");
+		if (RuleSetfib  == NULL)
+			err(1, "bitcode fault: RuleSetfib ");
+		RuleSetdscp = mod->getFunction("rule_setdscp");
+		if (RuleSetdscp  == NULL)
+			err(1, "bitcode fault: RuleSetdscp ");
+		RuleNat = mod->getFunction("rule_nat");
+		if (RuleNat  == NULL)
+			err(1, "bitcode fault: RuleNat ");
+		RuleReass = mod->getFunction("rule_reass");
+		if (RuleReass  == NULL)
+			err(1, "bitcode fault: RuleReass ");
 	}
 
 	// Allocate and initialize LLVM vars.
@@ -569,6 +911,7 @@
 	{
 		// Create the module and load the code.
 		mod = loadBitcode("rules.bc");
+		mod->dump();
 
 		Func = mod->getFunction("ipfw_chk_jit");
 		if (Func == NULL)
@@ -675,7 +1018,7 @@
 		Cmd = Irb.CreateAlloca(Ipfw_insnPtrTy, nullptr, "cmd");
 		Tablearg = Irb.CreateAlloca(Int32Ty, nullptr, "tablearg");
 		L = Irb.CreateAlloca(Int32Ty, nullptr, "l");
-		CmdLen = Irb.CreateAlloca(Int32Ty, nullptr, "cmdlen");
+		Cmdlen = Irb.CreateAlloca(Int32Ty, nullptr, "cmdlen");
 		SkipOr = Irb.CreateAlloca(Int32Ty, nullptr, "skipor");
 		F = Irb.CreateAlloca(Ip_fwPtrTy, nullptr, "f");
 
@@ -736,10 +1079,10 @@
 
 		// l = f->cmd_len;
 		Value *FL = Irb.CreateLoad(F);
-		Value *FCmdLen = Irb.CreateStructGEP(FL, 3);
-		Value *FCmdLenL = Irb.CreateLoad(FCmdLen);
-		Value *FCmdLenL32 = Irb.CreateZExt(FCmdLenL, Int32Ty);
-		Irb.CreateStore(FCmdLenL32, L);
+		Value *FCmdlen = Irb.CreateStructGEP(FL, 3);
+		Value *FCmdlenL = Irb.CreateLoad(FCmdlen);
+		Value *FCmdlenL32 = Irb.CreateZExt(FCmdlenL, Int32Ty);
+		Irb.CreateStore(FCmdlenL32, L);
 
 		// cmd = f->cmd;
 		Value *FCmd = Irb.CreateStructGEP(FL, 11);
@@ -756,7 +1099,7 @@
 		Value *Len = Irb.CreateLoad(LenPtr);
 		AndOp = Irb.CreateAnd(Len, ConstantInt::get(Int8Ty, F_LEN_MASK));
 		Value *AndOp32 = Irb.CreateSExt(AndOp, Int32Ty);
-		Irb.CreateStore(AndOp32, CmdLen);
+		Irb.CreateStore(AndOp32, Cmdlen);
 
 		// if (skip_or)
 		Value *SkipOrL = Irb.CreateLoad(SkipOr);
@@ -802,15 +1145,15 @@
 		// This are the increments of the for loop.
 		// l -= cmdlen, cmd += cmdlen;
 		Value *LL = Irb.CreateLoad(L);
-		Value *CmdLenL = Irb.CreateLoad(CmdLen);
-		Value *Sub = Irb.CreateNSWSub(LL, CmdLenL);
+		Value *CmdlenL = Irb.CreateLoad(Cmdlen);
+		Value *Sub = Irb.CreateNSWSub(LL, CmdlenL);
 		Irb.CreateStore(Sub, L);
 
 		// ipfw_insn *cmd; Add to pointer.
 		// Note: Since LLVM can't add to a ptr, we can use GEP with casted Ptr.
 		// cmd += cmdlen;
 		Value *CmdL = Irb.CreateLoad(Cmd);
-		Value *Add = Irb.CreateInBoundsGEP(CmdL, CmdLenL);
+		Value *Add = Irb.CreateInBoundsGEP(CmdL, CmdlenL);
 		Irb.CreateStore(Add, Cmd);
 
 		// if (cmd->len & F_NOT)
@@ -1206,9 +1549,13 @@
 	{
 	}
 
+	// XXX Exec not tested.
 	void
 	emit_ip_dst()
 	{
+		Value *IsIpv4L = Irb.CreateLoad(IsIpv4);
+		Value *CmdL = Irb.CreateLoad(Cmd);
+		Irb.CreateCall(RuleIpDst, {Match, IsIpv4L, CmdL, DstIp});
 	}
 
 	void
@@ -1225,117 +1572,126 @@
 	void
 	emit_ip_dstport()
 	{
-		// /*
-		//  * offset == 0 && proto != 0 is enough
-		//  * to guarantee that we have a
-		//  * packet with port info.
-		//  */
-		// if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
-		// 	&& offset == 0) {
-		// 	u_int16_t x =
-		// 		(cmd->opcode == O_IP_SRCPORT) ?
-		// 		src_port : dst_port ;
-		// 	u_int16_t *p =
-		// 		((ipfw_insn_u16 *)cmd)->ports;
-		// 	int i;
-
-		// 	for (i = cmdlen - 1; !match && i>0;
-		// 		i--, p += 2)
-		// 		match = (x>=p[0] && x<=p[1]);
-		//  }
-		BasicBlock *Yes = BasicBlock::Create(Con, "R_Yes", Func);
-		BasicBlock *Out = BasicBlock::Create(Con, "R_Out", Func);
-		BasicBlock *Src = BasicBlock::Create(Con, "R_Src", Func);
-		BasicBlock *Dst = BasicBlock::Create(Con, "R_Dst", Func);
-		BasicBlock *Loop = BasicBlock::Create(Con, "R_Loop", Func);
-		BasicBlock *ContLoop = BasicBlock::Create(Con, "R_ContLoop", Func);
-		Value *Comp;
-
-		// Perform allocations at the beginning.
-		Value *X = Irb.CreateAlloca(Int16Ty, nullptr, "x");
-		Value *P = Irb.CreateAlloca(Int16PtrTy, nullptr, "p");
-		Value *I = Irb.CreateAlloca(Int32Ty, nullptr, "i");
-		// p = ((ipfw_insn_u16 *)cmd)->ports;
-		Value *CmdLBitC = Irb.CreateBitCast(Cmd, IpfwInsnU16PtrTy);
-		Value *Ports = Irb.CreateStructGEP(CmdLBitC, 1);
-		Value *PortsGEP = Irb.CreateStructGEP(Ports, 0);
-		Irb.CreateStore(PortsGEP, P);
-		// New p
-		Value *PL = Irb.CreateLoad(P);
-
-		// (proto == IPPROTO_UDP || proto == IPPROTO_TCP)
+		// rule_ip_dstport(&match, proto, offset, cmd, cmdlen, dst_port, src_port);
 		Value *ProtoL = Irb.CreateLoad(Proto);
-		Value *Comp1 = Irb.CreateICmpEQ(ProtoL, ConstantInt::get(ProtoL->getType(), IPPROTO_TCP));
-		Value *Comp2 = Irb.CreateICmpEQ(ProtoL, ConstantInt::get(ProtoL->getType(), IPPROTO_UDP));
-		Value *OrComps = Irb.CreateOr(Comp1, Comp2);
-
-		// (Offset == 0)
 		Value *OffsetL = Irb.CreateLoad(Offset);
-		Value *Comp3 = Irb.CreateICmpEQ(OffsetL, ConstantInt::get(OffsetL->getType(), 0));
-		// (OrComps && Comp3)
-		Comp = Irb.CreateAnd(OrComps, Comp3);
-		Irb.CreateCondBr(Comp, Yes, Out);
-
-		// yes:
-		Irb.SetInsertPoint(Yes);
-		// if (cmd->opcode == O_IP_SRCPORT)
 		Value *CmdL = Irb.CreateLoad(Cmd);
-		Value *OpcodePtr = Irb.CreateStructGEP(CmdL, 0);
-		Value *Opcode = Irb.CreateLoad(OpcodePtr);
-		Comp = Irb.CreateICmpEQ(Opcode, ConstantInt::get(Opcode->getType(), O_IP_SRCPORT));
-		Irb.CreateCondBr(Comp, Src, Dst);
-	
-		Irb.SetInsertPoint(Src);
-		// 	u_int16_t x = src_port;
+		Value *CmdlenL = Irb.CreateLoad(Cmdlen);
+		Value *DstPortL = Irb.CreateLoad(DstPort);
 		Value *SrcPortL = Irb.CreateLoad(SrcPort);
-		Irb.CreateStore(SrcPortL, X);
-		Irb.CreateBr(Loop);
 
-		Irb.SetInsertPoint(Dst);
-		// 	u_int16_t x = dst_port;
-		Value *DstPortL = Irb.CreateLoad(DstPort);
-		Irb.CreateStore(DstPortL, X);
-		Irb.CreateBr(Loop);
+		Irb.CreateCall(RuleIpDstport, {Match, ProtoL, OffsetL, CmdL, CmdlenL, DstPortL, SrcPortL});
 
-		Irb.SetInsertPoint(Loop);
-		// Loop initialisation
-		// i = cmdlen - 1;
-		// cmdlen: signed
-		Value *CmdLenL = Irb.CreateLoad(CmdLen);
-		Value *Sub = Irb.CreateNSWSub(CmdLenL, ConstantInt::get(CmdLenL->getType(), 1));
-		Irb.CreateStore(Sub, I);
-		Irb.CreateBr(ContLoop);
-
-		// Check condition
-		Irb.SetInsertPoint(ContLoop);
-		// while((!match) && (i>0)) {
-		Value *IL = Irb.CreateLoad(I);
-		Value *MatchL = Irb.CreateLoad(Match);
-		Comp1 = Irb.CreateICmpEQ(MatchL, ConstantInt::get(MatchL->getType(), 0));
-		Comp2 = Irb.CreateICmpSGT(IL, ConstantInt::get(IL->getType(), 0));
-		Value *BreakCond = Irb.CreateAnd(Comp1, Comp2);
-		Irb.CreateCondBr(BreakCond, ContLoop, Out);
-
-		// 	match = ((x >= p[0]) && (x <= p[1]));
-		// FIXME
-		Value *PZ = Irb.CreateInBoundsGEP(PL, ConstantInt::get(Int32Ty, 0));
-		Value *PO = Irb.CreateInBoundsGEP(PL, ConstantInt::get(Int32Ty, 1));
-		Comp1 = Irb.CreateICmpUGE(X, PZ);
-		Comp2 = Irb.CreateICmpULE(X, PO);
-		Comp = Irb.CreateAnd(Comp1, Comp2);
-		Value *Comp32 = Irb.CreateSExt(Comp, MatchL->getType());
-		Irb.CreateStore(Comp32, Match);
-
-		// Increment, decrement.
-		// 	i--;
-		Value *ILD = Irb.CreateNSWSub(IL, ConstantInt::get(IL->getType(), 1));
-		Irb.CreateStore(ILD, I);
-		// 	p += 2;
-		Value *PGEP = Irb.CreateInBoundsGEP(PL, ConstantInt::get(Int32Ty, 2));
-		Irb.CreateStore(PGEP, P);
-		Irb.CreateBr(ContLoop);
+		// // /*
+		// //  * offset == 0 && proto != 0 is enough
+		// //  * to guarantee that we have a
+		// //  * packet with port info.
+		// //  */
+		// // if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
+		// // 	&& offset == 0) {
+		// // 	u_int16_t x =
+		// // 		(cmd->opcode == O_IP_SRCPORT) ?
+		// // 		src_port : dst_port ;
+		// // 	u_int16_t *p =
+		// // 		((ipfw_insn_u16 *)cmd)->ports;
+		// // 	int i;
+
+		// // 	for (i = cmdlen - 1; !match && i>0;
+		// // 		i--, p += 2)
+		// // 		match = (x>=p[0] && x<=p[1]);
+		// //  }
+		// BasicBlock *Yes = BasicBlock::Create(Con, "R_Yes", Func);
+		// BasicBlock *Out = BasicBlock::Create(Con, "R_Out", Func);
+		// BasicBlock *Src = BasicBlock::Create(Con, "R_Src", Func);
+		// BasicBlock *Dst = BasicBlock::Create(Con, "R_Dst", Func);
+		// BasicBlock *Loop = BasicBlock::Create(Con, "R_Loop", Func);
+		// BasicBlock *ContLoop = BasicBlock::Create(Con, "R_ContLoop", Func);
+		// Value *Comp;
+
+		// // Perform allocations at the beginning.
+		// Value *X = Irb.CreateAlloca(Int16Ty, nullptr, "x");
+		// Value *P = Irb.CreateAlloca(Int16PtrTy, nullptr, "p");
+		// Value *I = Irb.CreateAlloca(Int32Ty, nullptr, "i");
+		// // p = ((ipfw_insn_u16 *)cmd)->ports;
+		// Value *CmdLBitC = Irb.CreateBitCast(Cmd, IpfwInsnU16PtrTy);
+		// Value *Ports = Irb.CreateStructGEP(CmdLBitC, 1);
+		// Value *PortsGEP = Irb.CreateStructGEP(Ports, 0);
+		// Irb.CreateStore(PortsGEP, P);
+		// // New p
+		// Value *PL = Irb.CreateLoad(P);
+
+		// // (proto == IPPROTO_UDP || proto == IPPROTO_TCP)
+		// Value *ProtoL = Irb.CreateLoad(Proto);
+		// Value *Comp1 = Irb.CreateICmpEQ(ProtoL, ConstantInt::get(ProtoL->getType(), IPPROTO_TCP));
+		// Value *Comp2 = Irb.CreateICmpEQ(ProtoL, ConstantInt::get(ProtoL->getType(), IPPROTO_UDP));
+		// Value *OrComps = Irb.CreateOr(Comp1, Comp2);
+
+		// // (Offset == 0)
+		// Value *OffsetL = Irb.CreateLoad(Offset);
+		// Value *Comp3 = Irb.CreateICmpEQ(OffsetL, ConstantInt::get(OffsetL->getType(), 0));
+		// // (OrComps && Comp3)
+		// Comp = Irb.CreateAnd(OrComps, Comp3);
+		// Irb.CreateCondBr(Comp, Yes, Out);
+
+		// // yes:
+		// Irb.SetInsertPoint(Yes);
+		// // if (cmd->opcode == O_IP_SRCPORT)
+		// Value *CmdL = Irb.CreateLoad(Cmd);
+		// Value *OpcodePtr = Irb.CreateStructGEP(CmdL, 0);
+		// Value *Opcode = Irb.CreateLoad(OpcodePtr);
+		// Comp = Irb.CreateICmpEQ(Opcode, ConstantInt::get(Opcode->getType(), O_IP_SRCPORT));
+		// Irb.CreateCondBr(Comp, Src, Dst);
+	
+		// Irb.SetInsertPoint(Src);
+		// // 	u_int16_t x = src_port;
+		// Value *SrcPortL = Irb.CreateLoad(SrcPort);
+		// Irb.CreateStore(SrcPortL, X);
+		// Irb.CreateBr(Loop);
+
+		// Irb.SetInsertPoint(Dst);
+		// // 	u_int16_t x = dst_port;
+		// Value *DstPortL = Irb.CreateLoad(DstPort);
+		// Irb.CreateStore(DstPortL, X);
+		// Irb.CreateBr(Loop);
+
+		// Irb.SetInsertPoint(Loop);
+		// // Loop initialisation
+		// // i = cmdlen - 1;
+		// // cmdlen: signed
+		// Value *CmdlenL = Irb.CreateLoad(Cmdlen);
+		// Value *Sub = Irb.CreateNSWSub(CmdlenL, ConstantInt::get(CmdlenL->getType(), 1));
+		// Irb.CreateStore(Sub, I);
+		// Irb.CreateBr(ContLoop);
+
+		// // Check condition
+		// Irb.SetInsertPoint(ContLoop);
+		// // while((!match) && (i>0)) {
+		// Value *IL = Irb.CreateLoad(I);
+		// Value *MatchL = Irb.CreateLoad(Match);
+		// Comp1 = Irb.CreateICmpEQ(MatchL, ConstantInt::get(MatchL->getType(), 0));
+		// Comp2 = Irb.CreateICmpSGT(IL, ConstantInt::get(IL->getType(), 0));
+		// Value *BreakCond = Irb.CreateAnd(Comp1, Comp2);
+		// Irb.CreateCondBr(BreakCond, ContLoop, Out);
+
+		// // 	match = ((x >= p[0]) && (x <= p[1]));
+		// Value *PZ = Irb.CreateInBoundsGEP(PL, ConstantInt::get(Int32Ty, 0));
+		// Value *PO = Irb.CreateInBoundsGEP(PL, ConstantInt::get(Int32Ty, 1));
+		// Comp1 = Irb.CreateICmpUGE(X, PZ);
+		// Comp2 = Irb.CreateICmpULE(X, PO);
+		// Comp = Irb.CreateAnd(Comp1, Comp2);
+		// Value *Comp32 = Irb.CreateSExt(Comp, MatchL->getType());
+		// Irb.CreateStore(Comp32, Match);
+
+		// // Increment, decrement.
+		// // 	i--;
+		// Value *ILD = Irb.CreateNSWSub(IL, ConstantInt::get(IL->getType(), 1));
+		// Irb.CreateStore(ILD, I);
+		// // 	p += 2;
+		// Value *PGEP = Irb.CreateInBoundsGEP(PL, ConstantInt::get(Int32Ty, 2));
+		// Irb.CreateStore(PGEP, P);
+		// Irb.CreateBr(ContLoop);
 
-		Irb.SetInsertPoint(Out);
+		// Irb.SetInsertPoint(Out);
 	}
 
 	void
@@ -1391,6 +1747,8 @@
 	void
 	emit_tcpopts()
 	{
+		// if (rule_tcpopts(&match, hlen, ulp, proto, offset, cmd, m, args))
+		// 	goto pullup_failed;
 	}
 
 	void
@@ -1684,8 +2042,8 @@
 	printf("emit_inner_for_prologue()\n");
 	compiler.emit_inner_for_prologue();
 	// Rule to test
-	printf("testing rule\n");
-	compiler.emit_layer2();
+	printf("Testing rule compilation\n");
+	compiler.emit_ip_dst();
 	printf("emit_inner_for_epilogue()\n");
 	compiler.emit_inner_for_epilogue();
 	printf("emit_outer_for_epilogue()\n");
@@ -1705,7 +2063,7 @@
 	if (chain->n_rules == 0)
 		return (NULL);
 
-	// test_compilation();
+	test_compilation();
 
 	ipfwJIT compiler(chain->n_rules);
 
@@ -1731,6 +2089,7 @@
 			cmdlen = F_LEN(cmd);
 			compiler.emit_inner_for_prologue();
 			switch (cmd->opcode) {
+			printf("compiling opcode: %d\n", cmd->opcode);
 			case O_NOP:
 				compiler.emit_nop();
 				break;


More information about the svn-soc-all mailing list