From owner-freebsd-bugs@FreeBSD.ORG Mon May 12 15:40:00 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 9E27A23B 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 7BE82220C 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 s4CFe0xC081709 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 s4CFe04I081708; 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.s4CFe04I081708@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 [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 03E70236 for ; Mon, 12 May 2014 15:39:24 +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 D97012207 for ; Mon, 12 May 2014 15:39:23 +0000 (UTC) Received: from cgiserv.freebsd.org ([127.0.1.6]) by cgiserv.freebsd.org (8.14.8/8.14.8) with ESMTP id s4CFdNL5011902 for ; Mon, 12 May 2014 15:39:23 GMT (envelope-from nobody@cgiserv.freebsd.org) Received: (from nobody@localhost) by cgiserv.freebsd.org (8.14.8/8.14.8/Submit) id s4CFdNNT011901; Mon, 12 May 2014 15:39:23 GMT (envelope-from nobody) Message-Id: <201405121539.s4CFdNNT011901@cgiserv.freebsd.org> Date: Mon, 12 May 2014 15:39:23 GMT From: Bill Yuan To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: kern/189720: pps action for ipfw 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:00 -0000 >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: