Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: qemu-0.15.1 from pkgsrc/emulators/qemu does not work on recent NetBSD current



On Tue, Dec 13, 2011 at 03:33:04AM +0900, Ryo ONODERA wrote:
> Hi,
> 
> From: David Young <dyoung%pobox.com@localhost>, Date: Mon, 12 Dec 2011 
> 11:19:46 -0600
> 
> > On Tue, Dec 13, 2011 at 12:34:58AM +0900, Ryo ONODERA wrote:
> >> Hi,
> >> 
> >> From: Manuel Bouyer <bouyer%antioche.eu.org@localhost>, Date: Mon, 12 Dec 
> >> 2011 11:56:14 +0100
> >> 
> >> > On Sat, Dec 10, 2011 at 11:17:11PM +0900, Ryo ONODERA wrote:
> >> >> Setting up qemu is hard work...
> >> >> 
> >> >> I have the following problem.
> >> >> 
> >> >> On NetBSD current machine,
> >> >> # /sbin/ifconfig tap0 create
> >> >> # /sbin/ifconfig bridge0 create
> >> >> # /sbin/brconfig bridge0 add msk0
> > 
> > Is msk0's PROMISC flag set here?
> > 
> >> >> # /sbin/ifconfig bridge0 up
> > 
> > Here?
> > 
> >> >> # /sbin/ifconfig tap0 0.0.0.0 up
> > 
> > Here?
> > 
> >> >> # /sbin/brconfig bridge0 add tap0
> > 
> > Here?
> > 
> >> >> # dhclient tap0
> >> >> bound to 192.168.81.5
> > 
> > And here?
> 
> 1) When msk0 has no IP address, PROMISC flag is never set.
> 2) When msk0 has IP address (assigned before "/sbin/ifconfig tap0 create"),
> PROMISC flag is set just after "/sbin/brconfig bridge0 add msk0" (your
> first question), and qemu tap and bridge networking works properly.

Ok, I see what's going on.  Try the attached (compiled but untested)
patch.

Dave

-- 
David Young
dyoung%pobox.com@localhost    Urbana, IL    (217) 721-9981
Index: sys/net/if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.257
diff -u -p -r1.257 if.c
--- sys/net/if.c        16 Nov 2011 06:09:37 -0000      1.257
+++ sys/net/if.c        13 Dec 2011 01:02:34 -0000
@@ -1415,10 +1431,9 @@ int
 ifpromisc(struct ifnet *ifp, int pswitch)
 {
        int pcount, ret;
-       short flags, nflags;
+       short nflags;
 
        pcount = ifp->if_pcount;
-       flags = ifp->if_flags;
        if (pswitch) {
                /*
                 * Allow the device to be "placed" into promiscuous
@@ -1428,20 +1443,10 @@ ifpromisc(struct ifnet *ifp, int pswitch
                if (ifp->if_pcount++ != 0)
                        return 0;
                nflags = ifp->if_flags | IFF_PROMISC;
-               if ((nflags & IFF_UP) == 0)
-                       return 0;
        } else {
                if (--ifp->if_pcount > 0)
                        return 0;
                nflags = ifp->if_flags & ~IFF_PROMISC;
-               /*
-                * If the device is not configured up, we should not need to
-                * turn off promiscuous mode (device should have turned it
-                * off when interface went down; and will look at IFF_PROMISC
-                * again next time interface comes up).
-                */
-               if ((nflags & IFF_UP) == 0)
-                       return 0;
        }
        ret = if_flags_set(ifp, nflags);
        /* Restore interface state if not successful. */
@@ -2159,15 +2164,25 @@ if_flags_set(ifnet_t *ifp, const short f
        if (ifp->if_setflags != NULL)
                rc = (*ifp->if_setflags)(ifp, flags);
        else {
-               short cantflags;
+               short cantflags, chgdflags;
                struct ifreq ifr;
 
-               memset(&ifr, 0, sizeof(ifr));
+               chgdflags = ifp->if_flags ^ flags;
+               cantflags = chgdflags & IFF_CANTCHANGE;
 
-               cantflags = (ifp->if_flags ^ flags) & IFF_CANTCHANGE;
                if (cantflags != 0)
                        ifp->if_flags ^= cantflags;
 
+               /* If the interface isn't up, and the only flag that
+                * changed is IFF_PROMISC, then traditionally
+                * we do not call if_ioctl after setting/clearing that
+                * flag.  Uphold the tradition.
+                */
+               if (chgdflags == IFF_PROMISC && (ifp->if_flags & IFF_UP) == 0)
+                       return 0;
+
+               memset(&ifr, 0, sizeof(ifr));
+
                ifr.ifr_flags = flags & ~IFF_CANTCHANGE;
                rc = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, &ifr);
 


Home | Main Index | Thread Index | Old Index