From owner-freebsd-bugs@FreeBSD.ORG Mon May 12 15:40:01 2014 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id E2B8123D for ; Mon, 12 May 2014 15:40:00 +0000 (UTC) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BF3DA220E for ; Mon, 12 May 2014 15:40:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.8/8.14.8) with ESMTP id s4CFe0Be081774 for ; Mon, 12 May 2014 15:40:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.8/8.14.8/Submit) id s4CFe0JK081764; Mon, 12 May 2014 15:40:00 GMT (envelope-from gnats) Resent-Date: Mon, 12 May 2014 15:40:00 GMT Resent-Message-Id: <201405121540.s4CFe0JK081764@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Bill Yuan Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 5788D11C for ; Mon, 12 May 2014 15:36:31 +0000 (UTC) Received: from cgiserv.freebsd.org (cgiserv.freebsd.org [IPv6:2001:1900:2254:206a::50:4]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 382A521E5 for ; Mon, 12 May 2014 15:36:31 +0000 (UTC) Received: from cgiserv.freebsd.org ([127.0.1.6]) by cgiserv.freebsd.org (8.14.8/8.14.8) with ESMTP id s4CFaVgj010846 for ; Mon, 12 May 2014 15:36:31 GMT (envelope-from nobody@cgiserv.freebsd.org) Received: (from nobody@localhost) by cgiserv.freebsd.org (8.14.8/8.14.8/Submit) id s4CFaVw7010845; Mon, 12 May 2014 15:36:31 GMT (envelope-from nobody) Message-Id: <201405121536.s4CFaVw7010845@cgiserv.freebsd.org> Date: Mon, 12 May 2014 15:36:31 GMT From: Bill Yuan To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: kern/189721: pps action to support packet per second X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 May 2014 15:40:01 -0000 >Number: 189721 >Category: kern >Synopsis: pps action to support packet per second >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: update >Submitter-Id: current-users >Arrival-Date: Mon May 12 15:40:00 UTC 2014 >Closed-Date: >Last-Modified: >Originator: Bill Yuan >Release: FB10 Stable >Organization: cozilywork >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 limit duration Rule with the pps keyword will allow the first limit packets in each duration milliseconds usage: ipfw add pps 1 50 tcp from any to any >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: