Date: Tue, 15 Oct 2002 11:41:00 +0400 (MSD) From: Oleg Bulyzhin <oleg@rinet.ru> To: FreeBSD-gnats-submit@FreeBSD.org Cc: luigi@FreeBSD.org, noc@rinet.ru Subject: kern/44078: [PATCH] dummynet: per-flow queues may work incorrect Message-ID: <200210150741.g9F7f0Ar063877@lath.rinet.ru>
next in thread | raw e-mail | index | archive | help
>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 <oleg@rinet.ru> >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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210150741.g9F7f0Ar063877>