From owner-freebsd-bugs Tue Feb 5 7:10:19 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 5D2CD37B430 for ; Tue, 5 Feb 2002 07:10:06 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g15FA6110640; Tue, 5 Feb 2002 07:10:06 -0800 (PST) (envelope-from gnats) Received: from shaper.yandex.ru (shaper.yandex.ru [213.180.193.102]) by hub.freebsd.org (Postfix) with ESMTP id F0D1437B41F for ; Tue, 5 Feb 2002 07:04:13 -0800 (PST) Received: (from wawa@localhost) by shaper.yandex.ru (8.11.3/8.11.3) id g15ErJM09362; Tue, 5 Feb 2002 17:53:19 +0300 (MSK) (envelope-from wawa) Message-Id: <200202051453.g15ErJM09362@shaper.yandex.ru> Date: Tue, 5 Feb 2002 17:53:19 +0300 (MSK) From: wawa@yandex-team.ru Reply-To: wawa@yandex-team.ru To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.113 Subject: kern/34639: IPFW skipto works too slow Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Number: 34639 >Category: kern >Synopsis: IPFW skipto works too slow >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Feb 05 07:10:01 PST 2002 >Closed-Date: >Last-Modified: >Originator: Vladimir Ivanov >Release: FreeBSD 5.0-CURRENT i386 >Organization: OOO Yandex >Environment: System: FreeBSD shaper.yandex.ru 5.0-CURRENT FreeBSD 5.0-CURRENT #3: Mon Feb 4 13:34:01 MSK 2002 wawa@shaper.yandex.ru:/usr/src/sys/compile/TEST i386 >Description: The original implementation of skipto rule use brute-force to find the appropriate rule. The suggested implementation use indexed access. >How-To-Repeat: >Fix: --- ip_fw.c.original Fri Mar 9 11:13:08 2001 +++ ip_fw.c.hacked_by_wawa Tue Feb 5 17:44:56 2002 @@ -108,6 +108,8 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW, &fw_verbose_limit, 0, "Set upper limit of matches of ipfw rules logged"); +static struct ip_fw_chain *skiptohash[IPFW_DEFAULT_RULE]; + /* * Extension for stateful ipfw. * @@ -903,9 +905,8 @@ int rule = me->rule->fw_skipto_rule ; /* guess... */ if ( (me->rule->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_SKIPTO ) - for (chain = LIST_NEXT(me,next); chain ; chain = LIST_NEXT(chain,next)) - if (chain->rule->fw_number >= rule) - return chain ; + return skiptohash[rule]; + return LIST_NEXT(me,next) ; /* failure or not a skipto */ } @@ -1056,8 +1057,8 @@ if (skipto != 0) { if (skipto >= IPFW_DEFAULT_RULE) goto dropit; - while (chain && chain->rule->fw_number <= skipto) - chain = LIST_NEXT(chain, next); + chain = skiptohash[skipto]; + if (chain == NULL) goto dropit; } @@ -1528,6 +1529,8 @@ nbr += 100; ftmp->fw_number = frwl->fw_number = nbr; } + /* save the pointer in hash */ + skiptohash[ftmp->fw_number] = fwc; /* Got a valid number; now insert it, keeping the list ordered */ LIST_FOREACH(fcp, chainptr, next) { @@ -1561,6 +1564,7 @@ /* prevent access to rules while removing them */ s = splnet(); + skiptohash[number] = NULL; while (fcp && fcp->rule->fw_number == number) { struct ip_fw_chain *next; @@ -1897,6 +1901,7 @@ case IP_FW_FLUSH: s = splnet(); remove_dyn_rule(NULL, 1 /* force delete */); + memset(skiptohash,0,sizeof(skiptohash)); splx(s); while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) && fcp->rule->fw_number != IPFW_DEFAULT_RULE ) { @@ -2044,6 +2049,7 @@ return 0; case MOD_UNLOAD: s = splnet(); + memset(skiptohash, 0, sizeof(skiptohash)); ip_fw_chk_ptr = old_chk_ptr; ip_fw_ctl_ptr = old_ctl_ptr; remove_dyn_rule(NULL, 1 /* force delete */); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message