Implement promiscuous mode.

This commit is contained in:
thorpej 2000-11-09 05:57:38 +00:00
parent c4e14613b2
commit c1e8f10429

View File

@ -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: