Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Sep 2014 16:16:01 GMT
From:      dpl@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r273853 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
Message-ID:  <201409091616.s89GG1xx090647@socsvn.freebsd.org>

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



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