From owner-svn-soc-all@FreeBSD.ORG Thu Sep 18 13:28:48 2014 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C389471D for ; Thu, 18 Sep 2014 13:28:48 +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 AE45C603 for ; Thu, 18 Sep 2014 13:28:48 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id s8IDSm0M083761 for ; Thu, 18 Sep 2014 13:28:48 GMT (envelope-from dpl@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id s8IDSmrQ083759 for svn-soc-all@FreeBSD.org; Thu, 18 Sep 2014 13:28:48 GMT (envelope-from dpl@FreeBSD.org) Date: Thu, 18 Sep 2014 13:28:48 GMT Message-Id: <201409181328.s8IDSmrQ083759@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: r274302 - 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-1 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: Thu, 18 Sep 2014 13:28:48 -0000 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;