Source-Changes-HG archive

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

[src/trunk]: src/sys/net Fix ifpromisc() regression: if ifpromisc(ifp, 1) is ...



details:   https://anonhg.NetBSD.org/src/rev/3db7e5ab5f6f
branches:  trunk
changeset: 772291:3db7e5ab5f6f
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Wed Dec 28 02:14:57 2011 +0000

description:
Fix ifpromisc() regression: if ifpromisc(ifp, 1) is called, do set
IFF_PROMISC whether ifp is IFF_UP or not, but do not call ifp->if_ioctl
unless ifp is IFF_UP.

diffstat:

 sys/net/if.c |  36 +++++++++++++++++-------------------
 1 files changed, 17 insertions(+), 19 deletions(-)

diffs (81 lines):

diff -r 153b9400d503 -r 3db7e5ab5f6f sys/net/if.c
--- a/sys/net/if.c      Tue Dec 27 23:34:13 2011 +0000
+++ b/sys/net/if.c      Wed Dec 28 02:14:57 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.258 2011/11/27 14:55:57 jakllsch Exp $        */
+/*     $NetBSD: if.c,v 1.259 2011/12/28 02:14:57 dyoung Exp $  */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.258 2011/11/27 14:55:57 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.259 2011/12/28 02:14:57 dyoung Exp $");
 
 #include "opt_inet.h"
 
@@ -1415,10 +1415,9 @@
 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 +1427,10 @@
                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. */
@@ -2160,15 +2149,24 @@
        if (ifp->if_setflags != NULL)
                rc = (*ifp->if_setflags)(ifp, flags);
        else {
-               short cantflags;
+               short cantflags, chgdflags;
                struct ifreq ifr;
 
+               chgdflags = ifp->if_flags ^ flags;
+               cantflags = chgdflags & IFF_CANTCHANGE;
+
+               if (cantflags != 0)
+                       ifp->if_flags ^= cantflags;
+
+                /* Traditionally, we do not call if_ioctl after
+                 * setting/clearing only IFF_PROMISC if the interface
+                 * isn't IFF_UP.  Uphold that tradition.
+                */
+               if (chgdflags == IFF_PROMISC && (ifp->if_flags & IFF_UP) == 0)
+                       return 0;
+
                memset(&ifr, 0, sizeof(ifr));
 
-               cantflags = (ifp->if_flags ^ flags) & IFF_CANTCHANGE;
-               if (cantflags != 0)
-                       ifp->if_flags ^= cantflags;
-
                ifr.ifr_flags = flags & ~IFF_CANTCHANGE;
                rc = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, &ifr);
 



Home | Main Index | Thread Index | Old Index