NetBSD-Bugs archive

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

kern/49196: ifconfig -vlanif with IFF_PROMISC on doesn't work correctly



>Number:         49196
>Category:       kern
>Synopsis:       ifconfig -vlanif with IFF_PROMISC on doesn't work correctly
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Sep 12 08:35:00 +0000 2014
>Originator:     Ryota Ozaki
>Release:        current
>Organization:
>Environment:
NetBSD rangeley 7.99.1 NetBSD 7.99.1 (RANGELEY) #181: Fri Sep 12 13:09:35 JST 
2014  ozaki-r@(hidden):(hidden) amd64
>Description:
Detaching a parent interface from a VLAN interface in promiscuous mode causes 
an unexpected result: both interfaces still remain in promiscuous mode.

At least, the parent interface should leave promiscuous mode. I think the VLAN 
interface should leave as well. Actually there is no chance to turn promiscuous 
mode off once it's is unconfigured by vlan_unconfig.
>How-To-Repeat:
ifconfig wm1 10.0.0.2/24 up
ifconfig vlan0 create
ifconfig vlan0 up
ifconfig vlan0 vlan 10 vlanif wm1

# Setting vlan0 and wm1 promiscuous mode
tcpdump -i vlan0 &
ifconfig vlan0
ifconfig wm1

# Detaching vlan0 from wm1
ifconfig vlan0 -vlanif wm1
ifconfig wm1  # wm1 is still in promiscuous mode (unexpected)

ifconfig vlan0  # vlan0 is still in promiscuous mode (expected)

# Unsetting promiscuous mode
pkill tcpdump
sleep 1
ifconfig vlan0 # vlan0 is still in promiscuous mode (unexpected)

>Fix:
Index: sys/net/if_vlan.c
===================================================================
RCS file: /cvs/cvsroot/src/sys/net/if_vlan.c,v
retrieving revision 1.72
diff -u -p -r1.72 if_vlan.c
--- sys/net/if_vlan.c   12 Sep 2014 04:10:24 -0000      1.72
+++ sys/net/if_vlan.c   12 Sep 2014 08:21:18 -0000
@@ -400,6 +400,8 @@ vlan_unconfig(struct ifnet *ifp)
        ifv->ifv_if.if_mtu = 0;
        ifv->ifv_flags = 0;
 
+       if ((ifp->if_flags & IFF_PROMISC) != 0)
+               ifpromisc(ifp, 0);
        if_down(ifp);
        ifp->if_flags &= ~(IFF_UP|IFF_RUNNING);
        ifp->if_capabilities = 0;
@@ -484,6 +486,10 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd
                if ((error = copyin(ifr->ifr_data, &vlr, sizeof(vlr))) != 0)
                        break;
                if (vlr.vlr_parent[0] == '\0') {
+                       if (ifv->ifv_p != NULL) {
+                               if ((ifp->if_flags & IFF_PROMISC) != 0)
+                                       error = ifpromisc(ifv->ifv_p, 0);
+                       }
                        vlan_unconfig(ifp);
                        break;
                }



Home | Main Index | Thread Index | Old Index