From nobody@FreeBSD.org  Fri May 24 17:40:52 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115])
	by hub.freebsd.org (Postfix) with ESMTP id E15D8D72
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 24 May 2013 17:40:52 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from oldred.FreeBSD.org (oldred.freebsd.org [8.8.178.121])
	by mx1.freebsd.org (Postfix) with ESMTP id B998F363
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 24 May 2013 17:40:52 +0000 (UTC)
Received: from oldred.FreeBSD.org ([127.0.1.6])
	by oldred.FreeBSD.org (8.14.5/8.14.5) with ESMTP id r4OHeqC2022521
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 24 May 2013 17:40:52 GMT
	(envelope-from nobody@oldred.FreeBSD.org)
Received: (from nobody@localhost)
	by oldred.FreeBSD.org (8.14.5/8.14.5/Submit) id r4OHep9h022371;
	Fri, 24 May 2013 17:40:51 GMT
	(envelope-from nobody)
Message-Id: <201305241740.r4OHep9h022371@oldred.FreeBSD.org>
Date: Fri, 24 May 2013 17:40:51 GMT
From: Julian Stecklina <jsteckli@os.inf.tu-dresden.de>
To: freebsd-gnats-submit@FreeBSD.org
Subject: virtio network (if_vtnet) interacts badly with qemu 1.5.0
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         178955
>Category:       kern
>Synopsis:       [virtio] virtio network (if_vtnet) interacts badly with qemu 1.5.0
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-emulation
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 24 17:50:00 UTC 2013
>Closed-Date:    Sat Jun 15 03:58:57 UTC 2013
>Last-Modified:  Sat Jun 15 04:00:00 UTC 2013
>Originator:     Julian Stecklina
>Release:        10-CURRENT
>Organization:
TU Dresden
>Environment:
FreeBSD  10.0-CURRENT FreeBSD 10.0-CURRENT #5 r+6436670: Fri May 24 19:34:14 CEST 2013     root@cosel.inf.tu-dresden.de:/usr/obj/usr/home/julian/src/freebsd/sys/GENERIC  amd64
>Description:
I just compiled qemu 1.5.0 on Linux and noticed that virtio network seems to have problems updating the MAC filter table:

vtnet0: error setting host MAC filter table

As far as I understand, if_vtnet.c does the following in vtnet_rx_filter_mac. It appends two full struct vtnet_mac_tables (one for unicast and one for multicast) to the request. Each consists of the number of actual entries in the table and space for 128 (mostly unused) entries in total.

The qemu code parses this differently. It first reads the number of elements in the first table and then skips over so many MAC addresses and then expects the header to the second table (which in our case points to zero'd memory). Then it skips those 0 MAC entries as well and expects that it has consumed the whole request and returns an error, because there is still data left. The relevant code is in qemu/hw/net/virtio-net.c in virtio_net_handle_rx_mode.

This problem was introduced with the following commit in qemu:
http://git.qemu.org/?p=qemu.git;a=commit;h=921ac5d0f3a0df869db5ce4edf752f51d8b1596a


>How-To-Repeat:
Boot FreeBSD CURRENT in qemu 1.5.0 with virtio networking:
 qemu-system-x86_64 -net nic,model=virtio -net user -hda disk.img

In the FreeBSD system, issue
 ifconfig vtnet0 up

Kernel will fail to update MAC filter multiple times:
vtnet0: error setting host MAC filter table
>Fix:


Patch attached with submission follows:

commit 4775464859691e16b9ad75e0a55b610f7a8c4030
Author: Julian Stecklina <jsteckli@os.inf.tu-dresden.de>
Date:   Thu May 23 14:59:03 2013 +0200

    Workaround qemu changes in handling MAC filter updates

diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index ffc349a..6f00dfb 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -2470,9 +2470,9 @@ vtnet_rx_filter_mac(struct vtnet_softc *sc)
 	sglist_init(&sg, 4, segs);
 	error |= sglist_append(&sg, &hdr, sizeof(struct virtio_net_ctrl_hdr));
 	error |= sglist_append(&sg, &filter->vmf_unicast,
-	    sizeof(struct vtnet_mac_table));
+	    sizeof(uint32_t) + ETHER_ADDR_LEN*filter->vmf_unicast.nentries);
 	error |= sglist_append(&sg, &filter->vmf_multicast,
-	    sizeof(struct vtnet_mac_table));
+	    sizeof(uint32_t) + ETHER_ADDR_LEN*filter->vmf_multicast.nentries);
 	error |= sglist_append(&sg, &ack, sizeof(uint8_t));
 	KASSERT(error == 0 && sg.sg_nseg == 4,
 	    ("error adding MAC filtering message to sglist"));


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-emulation 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun May 26 00:09:38 UTC 2013 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=178955 
State-Changed-From-To: open->closed 
State-Changed-By: bryanv 
State-Changed-When: Sat Jun 15 03:58:56 UTC 2013 
State-Changed-Why:  
Fixed in HEAD r251769 

http://www.freebsd.org/cgi/query-pr.cgi?pr=178955 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/178955: commit references a PR
Date: Sat, 15 Jun 2013 03:55:11 +0000 (UTC)

 Author: bryanv
 Date: Sat Jun 15 03:55:04 2013
 New Revision: 251769
 URL: http://svnweb.freebsd.org/changeset/base/251769
 
 Log:
   Merge r250802 from bryanv/vtnetmq - Fix setting of the Rx filters
   
   QEMU 1.4 made the descriptor requirement stricter - the size of buffer
   descriptor must exactly match the number of MAC addresses provided.
   
   PR:		kern/178955
   MFC after:	5 days
 
 Modified:
   head/sys/dev/virtio/network/if_vtnet.c
 
 Modified: head/sys/dev/virtio/network/if_vtnet.c
 ==============================================================================
 --- head/sys/dev/virtio/network/if_vtnet.c	Sat Jun 15 01:35:52 2013	(r251768)
 +++ head/sys/dev/virtio/network/if_vtnet.c	Sat Jun 15 03:55:04 2013	(r251769)
 @@ -2470,9 +2470,9 @@ vtnet_rx_filter_mac(struct vtnet_softc *
  	sglist_init(&sg, 4, segs);
  	error |= sglist_append(&sg, &hdr, sizeof(struct virtio_net_ctrl_hdr));
  	error |= sglist_append(&sg, &filter->vmf_unicast,
 -	    sizeof(struct vtnet_mac_table));
 +	    sizeof(uint32_t) + filter->vmf_unicast.nentries * ETHER_ADDR_LEN);
  	error |= sglist_append(&sg, &filter->vmf_multicast,
 -	    sizeof(struct vtnet_mac_table));
 +	    sizeof(uint32_t) + filter->vmf_multicast.nentries * ETHER_ADDR_LEN);
  	error |= sglist_append(&sg, &ack, sizeof(uint8_t));
  	KASSERT(error == 0 && sg.sg_nseg == 4,
  	    ("error adding MAC filtering message to sglist"));
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
