summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c11
-rw-r--r--sys/net/if.h3
-rw-r--r--sys/net/if_ethersubr.c4
3 files changed, 15 insertions, 3 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 969963de5bff..a55114818e07 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1291,6 +1291,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
}
ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
(new_flags &~ IFF_CANTCHANGE);
+ if (new_flags & IFF_PPROMISC) {
+ /* Permanently promiscuous mode requested */
+ ifp->if_flags |= IFF_PROMISC;
+ } else if (ifp->if_pcount == 0) {
+ ifp->if_flags &= ~IFF_PROMISC;
+ }
if (ifp->if_ioctl)
(void) (*ifp->if_ioctl)(ifp, cmd, data);
getmicrotime(&ifp->if_lastchange);
@@ -1561,6 +1567,11 @@ ifpromisc(ifp, pswitch)
oldpcount = ifp->if_pcount;
oldflags = ifp->if_flags;
+ if (ifp->if_flags & IFF_PPROMISC) {
+ /* Do nothing if device is in permanently promiscuous mode */
+ ifp->if_pcount += pswitch ? 1 : -1;
+ return (0);
+ }
if (pswitch) {
/*
* If the device is not configured up, we cannot put it in
diff --git a/sys/net/if.h b/sys/net/if.h
index fc95786b7764..8453ff56eba3 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -140,11 +140,12 @@ struct if_data {
#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
#define IFF_MULTICAST 0x8000 /* supports multicast */
#define IFF_POLLING 0x10000 /* Interface is in polling mode. */
+#define IFF_PPROMISC 0x20000 /* user-requested promisc mode */
/* flags set internally only: */
#define IFF_CANTCHANGE \
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
- IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART)
+ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART|IFF_PROMISC)
/* Capabilities that interfaces can advertise. */
#define IFCAP_RXCSUM 0x0001 /* can offload checksum on RX */
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 53c744d7d09e..af1421d29592 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -677,7 +677,8 @@ ether_demux(ifp, eh, m)
if ((ifp->if_flags & IFF_PROMISC) != 0
&& (eh->ether_dhost[0] & 1) == 0
&& bcmp(eh->ether_dhost,
- IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0) {
+ IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0
+ && (ifp->if_flags && IFF_PPROMISC) == 0) {
m_freem(m);
return;
}
@@ -1076,4 +1077,3 @@ ether_resolvemulti(ifp, llsa, sa)
return EAFNOSUPPORT;
}
}
-