Skip site navigation (1)Skip section navigation (2)
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>