kern/189720: pps action for ipfw

Bill Yuan bycn82 at gmail.com
Mon May 12 15:40:00 UTC 2014


>Number:         189720
>Category:       kern
>Synopsis:       pps action for ipfw
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon May 12 15:40:00 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator:     Bill Yuan
>Release:        FB10Stable
>Organization:
cozilyworks
>Environment:
FreeBSD FB10Stable 10.0-STABLE FreeBSD 10.0-STABLE #0 r265900: Mon May 12 13:41:15 UTC 2014     root at FB10Stable:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
pps action for ipfw
pps: packet for second (millisecond)

usage:
    ipfw add pps 1 50 tcp from any to any


man page

 pps limit duration
             Rule with the pps keyword will allow the first limit packets in
             each duration milliseconds
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

Index: sbin/ipfw/ipfw.8
===================================================================
--- sbin/ipfw/ipfw.8	(revision 265916)
+++ sbin/ipfw/ipfw.8	(working copy)
@@ -603,6 +603,14 @@
 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 each 
+.Ar duration 
+milliseconds
 .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 265916)
+++ sbin/ipfw/ipfw2.c	(working copy)
@@ -244,6 +244,7 @@
 	{ "allow",		TOK_ACCEPT },
 	{ "permit",		TOK_ACCEPT },
 	{ "count",		TOK_COUNT },
+	{ "pps",		TOK_PPS },
 	{ "pipe",		TOK_PIPE },
 	{ "queue",		TOK_QUEUE },
 	{ "divert",		TOK_DIVERT },
@@ -1231,7 +1232,12 @@
 		case O_SKIPTO:
 			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_PIPE:
 			PRINT_UINT_ARG("pipe ", cmd->arg1);
 			break;
@@ -2985,7 +2991,23 @@
 	case TOK_COUNT:
 		action->opcode = O_COUNT;
 		break;
-
+	
+	case TOK_PPS:
+		action->opcode = O_PPS;
+		ipfw_insn_pps *p = (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)) {
+			p->duration = strtoul(*av, NULL, 10);
+			av++;
+		}else
+			errx(EX_USAGE,"illegal arugment pps `duration` %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 265916)
+++ sbin/ipfw/ipfw2.h	(working copy)
@@ -92,6 +92,7 @@
 	TOK_NGTEE,
 	TOK_FORWARD,
 	TOK_SKIPTO,
+	TOK_PPS,
 	TOK_DENY,
 	TOK_REJECT,
 	TOK_RESET,
Index: sys/netinet/ip_fw.h
===================================================================
--- sys/netinet/ip_fw.h	(revision 265916)
+++ sys/netinet/ip_fw.h	(working copy)
@@ -165,6 +165,7 @@
 	O_REJECT,		/* arg1=icmp arg (same as deny)	*/
 	O_COUNT,		/* none				*/
 	O_SKIPTO,		/* arg1=next rule number	*/
+	O_PPS,			/* arg1=limit, pps->duration */
 	O_PIPE,			/* arg1=pipe number		*/
 	O_QUEUE,		/* arg1=queue number		*/
 	O_DIVERT,		/* arg1=port number		*/
@@ -378,6 +379,15 @@
 } ipfw_insn_log;
 
 /*
+ * This is used for PPS
+ */
+typedef struct _ipfw_insn_pps{
+	ipfw_insn o;
+	uint32_t start_time;
+	uint16_t count;
+	uint16_t duration;
+} 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 265916)
+++ sys/netpfil/ipfw/ip_fw2.c	(working copy)
@@ -2179,7 +2179,24 @@
 			    skip_or = 0;
 			    continue;
 			    break;	/* not reached */
-
+			case O_PPS:{
+				ipfw_insn_pps *pps = (ipfw_insn_pps *)cmd;
+				if(pps->start_time+pps->duration >= ticks){
+					if(pps->count < cmd->arg1){
+						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: {
 				/*
 				 * Implementation of `subroutine' call/return,
Index: sys/netpfil/ipfw/ip_fw_sockopt.c
===================================================================
--- sys/netpfil/ipfw/ip_fw_sockopt.c	(revision 265916)
+++ sys/netpfil/ipfw/ip_fw_sockopt.c	(working copy)
@@ -702,6 +702,12 @@
 			if (cmdlen != F_INSN_SIZE(ipfw_insn_altq))
 				goto bad_size;
 			break;
+		
+		case O_PPS:
+			have_action=1;
+			if (cmdlen != F_INSN_SIZE(ipfw_insn_pps))
+				goto bad_size;
+			break;
 
 		case O_PIPE:
 		case O_QUEUE:
@@ -769,6 +775,7 @@
 				return EINVAL;
 			}
 			break;
+
 #ifdef INET6
 		case O_IP6_SRC:
 		case O_IP6_DST:
@@ -776,7 +783,6 @@
 			    F_INSN_SIZE(ipfw_insn))
 				goto bad_size;
 			break;
-
 		case O_FLOW6ID:
 			if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
 			    ((ipfw_insn_u32 *)cmd)->o.arg1)


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list