From owner-freebsd-bugs Tue Oct 15 0:50: 5 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D161737B401 for ; Tue, 15 Oct 2002 00:50:02 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1B69F43EAF for ; Tue, 15 Oct 2002 00:50:02 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.6/8.12.6) with ESMTP id g9F7o1Co034448 for ; Tue, 15 Oct 2002 00:50:01 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.6/8.12.6/Submit) id g9F7o1gF034447; Tue, 15 Oct 2002 00:50:01 -0700 (PDT) Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0F03137B401; Tue, 15 Oct 2002 00:41:03 -0700 (PDT) Received: from lath.rinet.ru (lath.rinet.ru [195.54.192.90]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1762743EB1; Tue, 15 Oct 2002 00:41:02 -0700 (PDT) (envelope-from oleg@lath.rinet.ru) Received: from lath.rinet.ru (localhost [127.0.0.1]) by lath.rinet.ru (8.12.6/8.12.6) with ESMTP id g9F7f0nO063878; Tue, 15 Oct 2002 11:41:00 +0400 (MSD) (envelope-from oleg@lath.rinet.ru) Received: (from oleg@localhost) by lath.rinet.ru (8.12.6/8.12.6/Submit) id g9F7f0Ar063877; Tue, 15 Oct 2002 11:41:00 +0400 (MSD) Message-Id: <200210150741.g9F7f0Ar063877@lath.rinet.ru> Date: Tue, 15 Oct 2002 11:41:00 +0400 (MSD) From: Oleg Bulyzhin Reply-To: Oleg Bulyzhin To: FreeBSD-gnats-submit@FreeBSD.org Cc: luigi@FreeBSD.org, noc@rinet.ru X-Send-Pr-Version: 3.113 Subject: kern/44078: [PATCH] dummynet: per-flow queues may work incorrect 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: 44078 >Category: kern >Synopsis: [PATCH] dummynet: per-flow queues may work incorrect >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Oct 15 00:50:00 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Oleg Bulyzhin >Release: FreeBSD 4.7-RC i386 >Organization: Cronyx Plus LLC >Environment: System: FreeBSD lath.rinet.ru 4.7-RC FreeBSD 4.7-RC #0: Wed Oct 9 11:24:09 MSD 2002 root@lath.rinet.ru:/l/usr/obj/l/usr/src/sys/lath i386 i believe whole RELENG_4 affected. >Description: find_queue() uses bcmp() for comparing two ipfw_flow_id structures. Due to gcc memory alignement sizeof(struct ipfw_flow_id) is 16 bytes but we have to compare only 14 bytes of data. Last 2 bytes may be filled with garbage (cause ip_input & ip_output functions define args structure as automatic variable). As result find_queue() often fails to find right queue and creates new one. Even more, in worst case pipe limits like bandwidth may not work. (i.e. packets which should be in same queue may split among many (up to 65536 in theory) queues resulting increased bandwidth). >How-To-Repeat: this example give us multiple queues with same id: sysctl net.inet.ip.dummynet.expire=0 ipfw pipe 1 config mask src-ip 0xffffffff ipfw add 10 pipe 1 ip from 127.0.0.1 to any ping -f -c 1000 -S 127.0.0.1 localhost > /dev/null ipfw pipe 1 show if we set net.inet.ip.dummynet.expire to 1 in previous example we'll see one queue (cause all others are expired) with quite low tot_pkt/bytes counters. >Fix: --- dummynet.patch begins here --- --- sys/netinet/ip_dummynet.c~ Fri Aug 16 14:53:44 2002 +++ sys/netinet/ip_dummynet.c Mon Oct 14 20:34:00 2002 @@ -883,7 +883,11 @@ searches++ ; for (prev=NULL, q = fs->rq[i] ; q ; ) { search_steps++; - if (bcmp(id, &(q->id), sizeof(q->id) ) == 0) + if (id->dst_ip == q->id.dst_ip && + id->src_ip == q->id.src_ip && + id->dst_port == q->id.dst_port && + id->src_port == q->id.src_port && + id->proto == q->id.proto ) break ; /* found */ else if (pipe_expire && q->head == NULL && q->S == q->F+1 ) { /* entry is idle and not in any heap, expire it */ --- dummynet.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message