socsvn commit: r273853 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
dpl at FreeBSD.org
dpl at FreeBSD.org
Tue Sep 9 16:16:02 UTC 2014
Author: dpl
Date: Tue Sep 9 16:16:01 2014
New Revision: 273853
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=273853
Log:
Added port filtering.
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 Tue Sep 9 16:15:21 2014 (r273852)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Tue Sep 9 16:16:01 2014 (r273853)
@@ -66,6 +66,7 @@
Type *Int32Ty;
Type *Int64Ty;
PointerType *Int8PtrTy;
+ PointerType *Int16PtrTy;
// Basic blocks used
BasicBlock *Entry;
@@ -97,15 +98,15 @@
Value *Oif;
Value *Hlen; //unsigned
Value *Offset; //unsigned
- Value *Ip6f_mf; //unsigned
+ Value *Ip6fMf; //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 *Dst_ip;
+ Value *SrcPort; //unsigned
+ Value *DstPort; //unsigned
+ Value *SrcIp;
+ Value *DstIp;
Value *Iplen; //unsigned
Value *Pktlen;
Value *Etype; //unsigned
@@ -113,36 +114,36 @@
Value *Q;
Value *Ulp;
- Value *Is_ipv4;
- Value *Is_ipv6;
- Value *Icmp6_type; //unsigned
- Value *Ext_hd; //unsigned
+ Value *IsIpv4;
+ Value *IsIpv6;
+ Value *Icmp6Type; //unsigned
+ Value *ExtHd; //unsigned
// This sets up some vars, at star time.
Function *InspectPkt;
// Auxiliary functions used by our JITed code.
// All this are used from our bitcode.
- Function *Is_icmp_query;
- Function *Flags_match;
- Function *Ipopts_match;
- Function *Tcpopts_match;
- Function *Iface_match;
- Function *Verify_path;
+ Function *IsIcmpQuery;
+ Function *FlagsMatch;
+ Function *IpoptsMatch;
+ Function *TcpoptsMatch;
+ Function *IfaceMatch;
+ Function *VerifyPath;
#ifdef INET6
- Function *Icmp6type_match;
- Function *Search_ip6_addr_net;
- Function *Flow6id_match;
- Function *Verify_path6;
- Function *Is_icmp6_query;
- Function *Send_reject6;
+ Function *Icmp6typeMatch;
+ Function *SearchIp6AddrNet;
+ Function *Flow6idMatch;
+ Function *VerifyPath6;
+ Function *IsIcmp6Query;
+ Function *SendReject6;
#endif /* INET6 */
- Function *Send_reject;
- Function *Set_match;
- Function *Jump_fast;
+ Function *SendReject;
+ Function *SetMatch;
+ Function *JumpFast;
Function *PrintfFunc;
- Function *Ipfw_find_rule;
+ Function *IpfwFindRule;
// Used structs.
StructType *IfnetTy;
@@ -152,6 +153,7 @@
StructType *Ip_fw_chainTy;
StructType *Ip_fwTy;
StructType *Ipfw_insnTy;
+ StructType *IpfwInsnU16Ty;
StructType *Ipfw_dyn_ruleTy;
StructType *Ipfw_insn_ifTy;
StructType *MbufTy;
@@ -165,6 +167,7 @@
PointerType *Ip_fw_chainPtrTy;
PointerType *Ip_fwPtrTy;
PointerType *Ipfw_insnPtrTy;
+ PointerType *IpfwInsnU16PtrTy;
PointerType *Ipfw_dyn_rulePtrTy;
PointerType *Ipfw_insn_ifPtrTy;
PointerType *MbufPtrTy;
@@ -219,6 +222,7 @@
Int32Ty = Type::getInt32Ty(Con);
Int64Ty = Type::getInt64Ty(Con);
Int8PtrTy = PointerType::getUnqual(Int8Ty);
+ Int16PtrTy = PointerType::getUnqual(Int16Ty);
// Get StrucType from bitcode.
MbufTy = mod->getTypeByName("struct.mbuf");
@@ -229,6 +233,7 @@
Ip_fw_chainTy = mod->getTypeByName("struct.ip_fw_chain");
Ip_fwTy = mod->getTypeByName("struct.ip_fw");
Ipfw_insnTy = mod->getTypeByName("struct._ipfw_insn");
+ IpfwInsnU16Ty = mod->getTypeByName("struct._ipfw_insn_u16");
Ipfw_insn_ifTy = mod->getTypeByName("struct._ipfw_insn_if");
Ipfw_dyn_ruleTy = mod->getTypeByName("struct._ipfw_dyn_rule");
#ifdef __FreeBSD__
@@ -246,6 +251,7 @@
Ip_fw_chainPtrTy = PointerType::getUnqual(Ip_fw_chainTy);
Ip_fwPtrTy = PointerType::getUnqual(Ip_fwTy);
Ipfw_insnPtrTy = PointerType::getUnqual(Ipfw_insnTy);
+ IpfwInsnU16PtrTy = PointerType::getUnqual(IpfwInsnU16Ty);
Ipfw_insn_ifPtrTy = PointerType::getUnqual(Ipfw_insn_ifTy);
Ipfw_dyn_rulePtrTy = PointerType::getUnqual(Ipfw_dyn_ruleTy);
#ifdef __FreeBSD__
@@ -254,29 +260,29 @@
// Get Function defs from bitcode.
// All of them are auxiliary functions.
InspectPkt = mod->getFunction("inspect_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");
+ IsIcmpQuery = mod->getFunction("is_icmp_query");
+ FlagsMatch = mod->getFunction("flags_match");
+ IpoptsMatch = mod->getFunction("ipopts_match");
+ TcpoptsMatch = mod->getFunction("tcpopts_match");
+ IfaceMatch = mod->getFunction("ifaceMatch");
+ VerifyPath = 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");
+ Icmp6typeMatch = mod->getFunction("icmp6type_match");
+ SearchIp6AddrNet = mod->getFunction("search_ip6_addr_net");
+ Flow6idMatch = mod->getFunction("flow6id_match");
+ VerifyPath6 = mod->getFunction("verify_path6");
+ IsIcmp6Query = mod->getFunction("is_icmp6_query");
+ SendReject6 = mod->getFunction("send_reject6");
#endif /* INET6 */
- Send_reject = mod->getFunction("send_reject");
- Set_match = mod->getFunction("set_match");
- Jump_fast = mod->getFunction("jump_fast");
+ SendReject = mod->getFunction("send_reject");
+ SetMatch = mod->getFunction("set_match");
+ JumpFast = mod->getFunction("jump_fast");
// Functions declared at bitcode.
PrintfFunc = mod->getFunction("printf");
- Ipfw_find_rule = mod->getFunction("ipfw_find_rule");
+ IpfwFindRule = mod->getFunction("ipfw_find_rule");
}
// Allocate and initialize LLVM vars.
@@ -320,8 +326,8 @@
Offset = Irb.CreateAlloca(Int16Ty, nullptr, "offset");
Irb.CreateStore(ConstantInt::get(Int16Ty, 0), Offset);
- Ip6f_mf = Irb.CreateAlloca(Int16Ty, nullptr, "ip6f_mf");
- Irb.CreateStore(ConstantInt::get(Int16Ty, 0), Ip6f_mf);
+ Ip6fMf = Irb.CreateAlloca(Int16Ty, nullptr, "ip6f_mf");
+ Irb.CreateStore(ConstantInt::get(Int16Ty, 0), Ip6fMf);
// proto = 0
Proto = Irb.CreateAlloca(Int8Ty, nullptr, "proto");
@@ -331,18 +337,18 @@
Value *FProto = Irb.CreateStructGEP(F_id, 5);
Irb.CreateStore(ConstantInt::get(Int8Ty, 0), FProto);
- Src_port = Irb.CreateAlloca(Int16Ty, nullptr, "src_port");
- Irb.CreateStore(ConstantInt::get(Int16Ty, 0), Src_port);
- Dst_port = Irb.CreateAlloca(Int16Ty, nullptr, "dst_port");
- Irb.CreateStore(ConstantInt::get(Int16Ty, 0), Dst_port);
+ SrcPort = Irb.CreateAlloca(Int16Ty, nullptr, "src_port");
+ Irb.CreateStore(ConstantInt::get(Int16Ty, 0), SrcPort);
+ DstPort = Irb.CreateAlloca(Int16Ty, nullptr, "dst_port");
+ Irb.CreateStore(ConstantInt::get(Int16Ty, 0), DstPort);
//src_ip.s_addr = 0;
- Src_ip = Irb.CreateAlloca(In_addrTy, nullptr, "src_ip");
- Value *Src_s_addr = Irb.CreateStructGEP(Src_ip, 0);
+ SrcIp = Irb.CreateAlloca(In_addrTy, nullptr, "src_ip");
+ Value *Src_s_addr = Irb.CreateStructGEP(SrcIp, 0);
Irb.CreateStore(ConstantInt::get(Int32Ty, 0), Src_s_addr);
//dst_ip.s_addr = 0;
- Dst_ip = Irb.CreateAlloca(In_addrTy, nullptr, "dst_ip");
- Value *Dst_s_addr = Irb.CreateStructGEP(Dst_ip, 0);
+ DstIp = Irb.CreateAlloca(In_addrTy, nullptr, "dst_ip");
+ Value *Dst_s_addr = Irb.CreateStructGEP(DstIp, 0);
Irb.CreateStore(ConstantInt::get(Int32Ty, 0), Dst_s_addr);
//iplen = 0;
@@ -371,23 +377,23 @@
Ulp = Irb.CreateAlloca(Int8PtrTy, nullptr, "ulp");
Irb.CreateStore(ConstantPointerNull::get(Int8PtrTy), Ulp);
- Is_ipv4 = Irb.CreateAlloca(Int32Ty, nullptr, "is_ipv4");
- Irb.CreateStore(ConstantInt::get(Int32Ty, 0), Is_ipv4);
- Is_ipv6 = Irb.CreateAlloca(Int32Ty, nullptr, "is_ipv6");
- Irb.CreateStore(ConstantInt::get(Int32Ty, 0), Is_ipv6);
- Icmp6_type = Irb.CreateAlloca(Int8Ty, nullptr, "icmp6_type");
- Irb.CreateStore(ConstantInt::get(Int8Ty, 0), Icmp6_type);
- Ext_hd = Irb.CreateAlloca(Int16Ty, nullptr, "ext_hd");
- Irb.CreateStore(ConstantInt::get(Int16Ty, 0), Ext_hd);
+ IsIpv4 = Irb.CreateAlloca(Int32Ty, nullptr, "is_ipv4");
+ Irb.CreateStore(ConstantInt::get(Int32Ty, 0), IsIpv4);
+ IsIpv6 = Irb.CreateAlloca(Int32Ty, nullptr, "is_ipv6");
+ Irb.CreateStore(ConstantInt::get(Int32Ty, 0), IsIpv6);
+ Icmp6Type = Irb.CreateAlloca(Int8Ty, nullptr, "icmp6_type");
+ Irb.CreateStore(ConstantInt::get(Int8Ty, 0), Icmp6Type);
+ ExtHd = Irb.CreateAlloca(Int16Ty, nullptr, "ext_hd");
+ Irb.CreateStore(ConstantInt::get(Int16Ty, 0), ExtHd);
// If it returns one, goto pullup_failed.
// Else, goto first rule.
Value *Ip = Irb.CreateLoad(IpPtr);
Value *UlpL = Irb.CreateLoad(Ulp);
- Value *InspectPktCall = Irb.CreateCall(InspectPkt, {Args, Ip, M, Src_ip,
- Dst_ip, Src_port, Dst_port, Etype, Ext_hd, Iplen, Pktlen, Is_ipv4,
- Is_ipv6, Hlen, Proto, Icmp6_type, Ip6f_mf, Offset, UlpL});
+ Value *InspectPktCall = Irb.CreateCall(InspectPkt, {Args, Ip, M, SrcIp,
+ DstIp, SrcPort, DstPort, Etype, ExtHd, Iplen, Pktlen, IsIpv4,
+ IsIpv6, Hlen, Proto, Icmp6Type, Ip6fMf, Offset, UlpL});
Value *Comp = Irb.CreateICmpEQ(InspectPktCall, ConstantInt::get(Int32Ty, 1));
Irb.CreateCondBr(Comp, PullupFailed, CheckTag);
@@ -492,7 +498,7 @@
Value *RulenumL = Irb.CreateLoad(Rulenum);
Value *RuleId = Irb.CreateStructGEP(Rule, 2);
Value *RuleIdL = Irb.CreateLoad(RuleId);
- Value *FindRuleCall = Irb.CreateCall3(Ipfw_find_rule, Chain, RulenumL, RuleIdL);
+ Value *FindRuleCall = Irb.CreateCall3(IpfwFindRule, Chain, RulenumL, RuleIdL);
Irb.CreateStore(FindRuleCall, FPos);
// Branch to Nottagged because it
@@ -752,7 +758,6 @@
Value *Sub = Irb.CreateNSWSub(LL, CmdLenL);
Irb.CreateStore(Sub, L);
- // TODO - Should ensure correctness of code.
// ipfw_insn *cmd; Add to pointer.
// Note: Since LLVM can't add to a ptr, we can use GEP with casted Ptr.
// cmd += cmdlen;
@@ -995,7 +1000,7 @@
//*match = iface_match(m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, chain, tablearg);
Value *rcvif = Irb.CreateStructGEP(Irb.CreateStructGEP(Irb.CreateLoad(MPtr), 5), 0);
Value *cmdc = Irb.CreateBitCast(Cmd, Ipfw_insn_ifPtrTy);
- Value *IfaceMatchCall = Irb.CreateCall4(Iface_match, rcvif, cmdc, Chain, Tablearg);
+ Value *IfaceMatchCall = Irb.CreateCall4(IfaceMatch, rcvif, cmdc, Chain, Tablearg);
Irb.CreateStore(IfaceMatchCall, Match);
}
@@ -1005,7 +1010,7 @@
{
//*match = iface_match(oif, (ipfw_insn_if *)cmd, chain, tablearg);
Value *Cmdc = Irb.CreateBitCast(Cmd, Ipfw_insn_ifPtrTy);
- Value *IfaceMatchCall = Irb.CreateCall4(Iface_match, Oif, Cmdc, Chain, Tablearg);
+ Value *IfaceMatchCall = Irb.CreateCall4(IfaceMatch, Oif, Cmdc, Chain, Tablearg);
Irb.CreateStore(IfaceMatchCall, Match);
}
@@ -1126,6 +1131,110 @@
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;
+ // XXX TODO Ensure correctness.
+ CmdLBitC = Irb.CreateBitCast(Cmd, IpfwInsnU16PtrTy);
+ Value *Ports = Irb.CreateStructGEP(CMDLBitC, 1);
+ Irb.CreateStore(PortsPtr, P);
+ Value *PL = Irb.CreateLoad(P);
+
+ // (proto == IPPROTO_UDP || proto == IPPROTO_TCP)
+ Value *Comp1 = Irb.CreateICmpEQ(Proto, ConstantInt::get(Proto->getType(), IPPROTO_TCP));
+ Value *Comp2 = Irb.CreateICmpEQ(Proto, ConstantInt::get(Proto->getType(), IPPROTO_UDP));
+ Value *OrComps = Irb.CreateOr(Comp1, Comp2);
+
+ // (Offset == 0)
+ Value *Comp3 = Irb.CreateICmpEQ(Offset, ConstantInt::get(Offset->getType(), 0));
+ // (OrComps && Comp3)
+ Value *Comp = Irb.CreateAnd(OrComps, Comp3);
+ Irb.CreateCondBr(Comp, Yes, Out);
+
+ // yes:
+ Irb.SetInserPoint(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.SetInserPoint(Src);
+ // u_int16_t x = src_port;
+ Irb.CreateStore(SrcPort, X);
+ Irb.CreateBr(Loop);
+
+ Irb.SetInserPoint(Dst);
+ // u_int16_t x = dst_port;
+ Irb.CreateStore(DstPort, X);
+ Irb.CreateBr(Loop);
+
+ Irb.SetInserPoint(Loop);
+ // Loop initialisation
+ // i = cmdlen - 1;
+ // cmdlen: signed
+ Value *Sub = Irb.CreateNSWSub(CmdLen, ConstantInt::get(CmdLen->getType(), 1);
+ Irb.CreateStore(Sub, I);
+ Irb.CreateBr(ContLoop);
+
+ // Check condition
+ Irb.SetInserPoint(ContLoop);
+ // while((!match) && (i>0)) {
+ Value *IL = Irb.CreateLoad(I);
+ Value *MatchL = Irb.CreateLoad(Match);
+ Comp1 = Irb.CreateICmpEQ(MatchL, ConstantInt::get(Match->getType(), 0)
+ Comp2 = Irb.CreateICmpSGT(IL, ConstantInt::get(I->getType(), 0)
+ Value *BreakCond = Irb.CreateAnd(Comp1, Comp2);
+ Irb.CreateCondBr(BreakCond, ContLoop, Out);
+
+ // match = ((x >= p[0]) && (x <= p[1]));
+ Value *PZ = Irb.CreateStructGEP(PL, 0);
+ Value *PO = Irb.CreateStructGEP(PL, 1);
+ Comp1 = Irb.CreateICmpUGE(X, PZ);
+ Comp2 = Irb.CreateICmpULE(X, PO);
+ Comp = Irb.CreateAnd(Comp1, Comp2);
+ Value *Comp32 = Irb.CreateSExt(Comp, Match->getType());
+ Irb.CreateStore(Comp32, Match);
+
+ // Increment, decrement.
+ // i--;
+ Value *ILD = Irb.CreateNSWSub(IL, ConstantInt::get(I->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);
}
// XXX Not tested.
More information about the svn-soc-all
mailing list