>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@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:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to