Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Jun 2014 00:10:26 +0800
From:      "bycn82" <bycn82@gmail.com>
To:        "'Luigi Rizzo'" <rizzo@iet.unipi.it>
Cc:        "'Alexander V. Chernikov'" <melifaro@ipfw.ru>, 'FreeBSD Net' <net@FreeBSD.org>
Subject:   RE: [CFT]: ipfw named tables / different tabletypes
Message-ID:  <000401cf80d8$ad1bb840$075328c0$@gmail.com>
In-Reply-To: <20140605155402.GA81905@onelab2.iet.unipi.it>
References:  <20140521204826.GA67124@onelab2.iet.unipi.it> <537E1029.70007@FreeBSD.org> <20140522154740.GA76448@onelab2.iet.unipi.it> <537E2153.1040005@FreeBSD.org> <20140522163812.GA77634@onelab2.iet.unipi.it> <538B2FE5.6070407@FreeBSD.org> <539044E4.1020904@ipfw.ru> <000c01cf80be$41194370$c34bca50$@gmail.com> <20140605134256.GA81234@onelab2.iet.unipi.it> <000001cf80cd$5dc1d9b0$19458d10$@gmail.com> <20140605155402.GA81905@onelab2.iet.unipi.it>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Sorry for waste you time to explain it again, I will read the code first.

And the latest patch of `PPS` should be OK, I checked the logic carefully this time. I sent it out last weekend.

logic as below, PPS actually will be fulfilled using `PPT`,(N packets per M ticks).


+			case O_PPT:
+			case O_PPS:{
+				ipfw_insn_pps *pps = (ipfw_insn_pps *)cmd;
+				if(pps->limit==0){
+					int limit,duration_in_ticks;
+					if(1000/hz > pps->duration){
+						duration_in_ticks=1;
+					}else{
+						duration_in_ticks=(pps->duration * hz +500)/1000;
+					}	
+					limit=(cmd->arg1 *1000 * duration_in_ticks + hz * pps->duration/2)/(hz * pps->duration);
+					pps->limit=limit;
+					pps->duration_in_ticks=duration_in_ticks;
+				}
+				if(pps->start_time+pps->duration_in_ticks>= ticks){
+					if(pps->count < pps->limit){
+						retval = IP_FW_PASS;
+					}else{
+						retval = IP_FW_DENY;
+					}
+					pps->count++;
+				}else{
+					pps->start_time=ticks;
+					pps->count=1;
+					retval = IP_FW_PASS;
+				}
+				l = 0;		
+				done = 1;
+				break;	
+			}

 

> -----Original Message-----
> From: 'Luigi Rizzo' [mailto:rizzo@iet.unipi.it]
> Sent: 05 June, 2014 23:54
> To: bycn82
> Cc: 'Alexander V. Chernikov'; 'FreeBSD Net'
> Subject: Re: [CFT]: ipfw named tables / different tabletypes
> 
> On Thu, Jun 05, 2014 at 10:49:27PM +0800, bycn82 wrote:
> > Hi Luigi,
> > Yes, use string instead of integer for the ID of table, but the same
> method cannot apply to the feature `set type of table`. And in the
> kernel, compare string will cause more than compare an integer.  In my
> opinion, actually they are just alias name for the object. Users already
> accept that every object has an integer ID.
> 
> Bill,
> I appreciate your enthusiasm on contributing to the project, but before
> starting to code, you (and everyone else, including myself) should spend
> some time at the drawing board, question your assumptions, and consider
> possible implementations.
> 
> Also the fact that previous implementations had bugs or restrictions
> does not imply that we should repeat the same mistakes now.
> 
> Specifically:
> 
> - comparing strings in the kernel is perfectly fine, we do it all the
>   time (sysctl names, filenames, interfaces and whatnot).
>   What would be terribly wrong is having to do, on every packet,
>   an expensive string or number lookup (note- it's the entire lookup
>   process, not a string comparison) to locate the table.
>   However, this is not the case.
>   The way to implement named objects (tables etc.) is to accept strings
>   as object names, and when the rule is added the string is checked
>   and converted to a pointers or an integer which permits direct
>   access to the table.
>   This is as fast as it can be at runtime, which is all what matters.
> 
> - at the moment tables and pipes have a single ID, which happens to be a
>   sequence of digits for mostly historical reasons (you can read it
>   as laziness of the original authors; i can take the blame for pipes).
> 
>   If we extend the namespace to include strings we improve the user's
>   experience and remain compatible with the existing user interface.
> 
>   Instead, if we require users to create a mapping before using
>   alphanumeric names, not only we add a step that was not there before,
>   but also create two names for the same object which makes it harder
>   to reason about the rulesets, and there is also the issue of how
>   to handle references to non-existing tables (which are trivially
>   supported now or with the approach i suggested, and would instead
>   require rescanning the ruleset whenever a name-number association
>   is added or deleted.
>      Another troubles with that approach is that you opening a race
>   window between the creation of the name-number mapping and its use,
>   and this is also something you don't want in a security-related tool.
> 
> We have had a similar discussion about your 'pps' extension for ipfw:
> useful feature, but your various implementations have issues (even the
> final one), and we have only so much time for reviewing patches; please
> do not burn it.
> 
> cheers
> luigi

[-- Attachment #2 --]
Index: sbin/ipfw/ipfw.8
===================================================================
--- sbin/ipfw/ipfw.8	(revision 266886)
+++ sbin/ipfw/ipfw.8	(working copy)
@@ -602,6 +602,22 @@
 Note: logging is done after all other packet matching conditions
 have been successfully verified, and before performing the final
 action (accept, deny, etc.) on the packet.
+.It Cm pps Ar limit duration
+Rule with the 
+.Cm pps
+keyword will allow the first
+.Ar limit
+packets in recent 
+.Ar duration 
+milliseconds.
+.It Cm ppt Ar limit duration
+Rule with the 
+.Cm ppt
+keyword will allow the first
+.Ar limit
+packets in recent 
+.Ar duration 
+ticks.
 .It Cm tag Ar number
 When a packet matches a rule with the
 .Cm tag
Index: sbin/ipfw/ipfw2.c
===================================================================
--- sbin/ipfw/ipfw2.c	(revision 266886)
+++ sbin/ipfw/ipfw2.c	(working copy)
@@ -244,6 +244,8 @@
 	{ "allow",		TOK_ACCEPT },
 	{ "permit",		TOK_ACCEPT },
 	{ "count",		TOK_COUNT },
+	{ "pps",		TOK_PPS },
+	{ "ppt",		TOK_PPT },
 	{ "pipe",		TOK_PIPE },
 	{ "queue",		TOK_QUEUE },
 	{ "divert",		TOK_DIVERT },
@@ -1232,6 +1234,20 @@
 			PRINT_UINT_ARG("skipto ", cmd->arg1);
 			break;
 
+		case O_PPS:
+			{
+			ipfw_insn_pps *pps=(ipfw_insn_pps *)cmd;
+			printf("pps %d %d",cmd->arg1,pps->duration);
+			break;			
+			}
+			
+		case O_PPT:
+			{
+			ipfw_insn_pps *pps=(ipfw_insn_pps *)cmd;
+			printf("ppt %d %d",pps->limit,pps->duration_in_ticks);
+			break;			
+			}
+
 		case O_PIPE:
 			PRINT_UINT_ARG("pipe ", cmd->arg1);
 			break;
@@ -2985,7 +3001,43 @@
 	case TOK_COUNT:
 		action->opcode = O_COUNT;
 		break;
+		
+	case TOK_PPS:
+		action->opcode = O_PPS;
+		ipfw_insn_pps *pps = (ipfw_insn_pps *)action;
+		action->len = F_INSN_SIZE(ipfw_insn_pps);
+		if (isdigit(**av)) {
+			action->arg1 = strtoul(*av, NULL, 10);
+			av++;
+		}else{
+			errx(EX_USAGE, "illegal argument pps `limit` %s", *av);
+		}
+		if (isdigit(**av)) {
+			pps->duration= strtoul(*av, NULL, 10);
+			av++;	
+		}else{
+			errx(EX_USAGE,"illegal arugment pps `duration` %s", *av);
+		}
+		break;	
 
+	case TOK_PPT:
+		action->opcode = O_PPT;
+		ipfw_insn_pps *ppt = (ipfw_insn_pps *)action;
+		action->len = F_INSN_SIZE(ipfw_insn_pps);
+		if (isdigit(**av)) {
+			ppt->limit = strtoul(*av, NULL, 10);
+			av++;
+		}else{
+			errx(EX_USAGE, "illegal argument ppt `limit` %s", *av);
+		}
+		if (isdigit(**av)) {
+			ppt->duration_in_ticks= strtoul(*av, NULL, 10);
+			av++;	
+		}else{
+			errx(EX_USAGE,"illegal arugment ppt `ticks` %s", *av);
+		}
+		break;	
+
 	case TOK_NAT:
 		action->opcode = O_NAT;
 		action->len = F_INSN_SIZE(ipfw_insn_nat);
Index: sbin/ipfw/ipfw2.h
===================================================================
--- sbin/ipfw/ipfw2.h	(revision 266886)
+++ sbin/ipfw/ipfw2.h	(working copy)
@@ -92,6 +92,8 @@
 	TOK_NGTEE,
 	TOK_FORWARD,
 	TOK_SKIPTO,
+	TOK_PPS,
+	TOK_PPT,
 	TOK_DENY,
 	TOK_REJECT,
 	TOK_RESET,
Index: sys/netinet/ip_fw.h
===================================================================
--- sys/netinet/ip_fw.h	(revision 266886)
+++ sys/netinet/ip_fw.h	(working copy)
@@ -165,6 +165,8 @@
 	O_REJECT,		/* arg1=icmp arg (same as deny)	*/
 	O_COUNT,		/* none				*/
 	O_SKIPTO,		/* arg1=next rule number	*/
+	O_PPS,			/* arg1=limit, pps->duration */
+	O_PPT,			/* pps->limit, pps->duration_in_ticks */
 	O_PIPE,			/* arg1=pipe number		*/
 	O_QUEUE,		/* arg1=queue number		*/
 	O_DIVERT,		/* arg1=port number		*/
@@ -378,6 +380,18 @@
 } ipfw_insn_log;
 
 /*
+ *	This is used for PPS
+ */
+typedef struct _ipfw_insn_pps{
+	ipfw_insn o;
+	uint32_t start_time;
+	uint32_t count;
+	uint32_t duration;			
+	uint32_t limit;
+	uint32_t duration_in_ticks;
+} ipfw_insn_pps;
+
+/*
  * Data structures required by both ipfw(8) and ipfw(4) but not part of the
  * management API are protected by IPFW_INTERNAL.
  */
Index: sys/netpfil/ipfw/ip_fw2.c
===================================================================
--- sys/netpfil/ipfw/ip_fw2.c	(revision 266886)
+++ sys/netpfil/ipfw/ip_fw2.c	(working copy)
@@ -2188,6 +2188,37 @@
 			    skip_or = 0;
 			    continue;
 			    break;	/* not reached */
+			    
+			case O_PPT:
+			case O_PPS:{
+				ipfw_insn_pps *pps = (ipfw_insn_pps *)cmd;
+				if(pps->limit==0){
+					int limit,duration_in_ticks;
+					if(1000/hz > pps->duration){
+						duration_in_ticks=1;
+					}else{
+						duration_in_ticks=(pps->duration * hz +500)/1000;
+					}	
+					limit=(cmd->arg1 *1000 * duration_in_ticks + hz * pps->duration/2)/(hz * pps->duration);
+					pps->limit=limit;
+					pps->duration_in_ticks=duration_in_ticks;
+				}
+				if(pps->start_time+pps->duration_in_ticks>= ticks){
+					if(pps->count < pps->limit){
+						retval = IP_FW_PASS;
+					}else{
+						retval = IP_FW_DENY;
+					}
+					pps->count++;
+				}else{
+					pps->start_time=ticks;
+					pps->count=1;
+					retval = IP_FW_PASS;
+				}
+				l = 0;		
+				done = 1;
+				break;	
+			}
 
 			case O_CALLRETURN: {
 				/*
Index: sys/netpfil/ipfw/ip_fw_sockopt.c
===================================================================
--- sys/netpfil/ipfw/ip_fw_sockopt.c	(revision 266886)
+++ sys/netpfil/ipfw/ip_fw_sockopt.c	(working copy)
@@ -703,6 +703,13 @@
 				goto bad_size;
 			break;
 
+		case O_PPS:
+		case O_PPT:
+			have_action=1;
+			if (cmdlen != F_INSN_SIZE(ipfw_insn_pps))
+				goto bad_size;
+			break;
+
 		case O_PIPE:
 		case O_QUEUE:
 			if (cmdlen != F_INSN_SIZE(ipfw_insn))

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?000401cf80d8$ad1bb840$075328c0$>