From c1e8f1042940ddf6951d8cbc88c2a0755bc3a703 Mon Sep 17 00:00:00 2001 From: thorpej Date: Thu, 9 Nov 2000 05:57:38 +0000 Subject: [PATCH] Implement promiscuous mode. --- sys/net/if_vlan.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 70211b506146..a625dcf35d07 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_vlan.c,v 1.16 2000/10/15 11:58:26 bouyer Exp $ */ +/* $NetBSD: if_vlan.c,v 1.17 2000/11/09 05:57:38 thorpej Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -85,8 +85,6 @@ * * - Need a way to facilitate parent interfaces that can do * tag insertion and/or extraction in hardware. - * - * - Need to make promiscuous mode work. */ #include "opt_inet.h" @@ -147,8 +145,11 @@ struct ifvlan { } ifv_mib; LIST_HEAD(__vlan_mchead, vlan_mc_entry) ifv_mc_listhead; LIST_ENTRY(ifvlan) ifv_list; + int ifv_flags; }; +#define IFVF_PROMISC 0x01 /* promiscuous mode enabled */ + #define ifv_ec ifv_u.ifvu_ec #define ifv_if ifv_ec.ec_if @@ -379,6 +380,7 @@ vlan_unconfig(struct ifnet *ifp) ifv->ifv_p = NULL; ifv->ifv_if.if_mtu = 0; + ifv->ifv_flags = 0; if_down(ifp); ifp->if_flags &= ~(IFF_UP|IFF_RUNNING); @@ -405,6 +407,29 @@ vlan_ifdetach(struct ifnet *p) splx(s); } +static int +vlan_set_promisc(struct ifnet *ifp) +{ + struct ifvlan *ifv = ifp->if_softc; + int error; + + if ((ifp->if_flags & IFF_PROMISC) != 0) { + if ((ifv->ifv_flags & IFVF_PROMISC) == 0) { + error = ifpromisc(ifv->ifv_p, 1); + if (error == 0) + ifv->ifv_flags |= IFVF_PROMISC; + } + } else { + if ((ifv->ifv_flags & IFVF_PROMISC) != 0) { + error = ifpromisc(ifv->ifv_p, 0); + if (error == 0) + ifv->ifv_flags &= ~IFVF_PROMISC; + } + } + + return (error); +} + static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { @@ -477,6 +502,9 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; ifv->ifv_tag = vlr.vlr_tag; ifp->if_flags |= IFF_RUNNING; + + /* Update promiscuous mode, if necessary. */ + vlan_set_promisc(ifp); break; case SIOCGETVLAN: @@ -491,14 +519,11 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCSIFFLAGS: /* - * XXX We don't support promiscuous mode right now because - * it would require help from the underlying drivers, which - * hasn't been implemented. + * For promiscuous mode, we enable promiscuous mode on + * the parent if we need promiscuous on the VLAN interface. */ - if ((ifr->ifr_flags & IFF_PROMISC) != 0) { - ifp->if_flags &= ~(IFF_PROMISC); - error = EINVAL; - } + if (ifv->ifv_p != NULL) + error = vlan_set_promisc(ifp); break; case SIOCADDMULTI: