Fix a number of minor bugs in the VLAN code:

* Initialize the "struct sockaddr_dl sdl" correctly in vlan_setmulti().

  PR: kern/22181

* The driver used to call malloc(..., M_NOWAIT), but to not check the
  return value. Change malloc(..., M_NOWAIT) to malloc(..., M_WAITOK)
  because the corresponding part of code is called from the upper
  half of the kernel only.

  PR: kern/22181

* Make sure a parent interface is up and running before invoking
  its if_start() routine in order to avoid system panic.

  PR: kern/22179 kern/24741 i386/25478

* Do not copy all the flags from a parent mindlessly.

  PR: kern/22179

* Do not call if_down() on a parent interface if it's already down.
  Call if_down() at splimp because if_down() needs that.

  PR: kern/22179

Reviewed by: wollman
This commit is contained in:
Yaroslav Tykhiy 2001-03-28 15:52:12 +00:00
parent 9112dc499f
commit 249932144b

View file

@ -120,8 +120,10 @@ vlan_setmulti(struct ifnet *ifp)
sc = ifp->if_softc;
ifp_p = sc->ifv_p;
sdl.sdl_len = ETHER_ADDR_LEN;
bzero((char *)&sdl, sizeof sdl);
sdl.sdl_len = sizeof sdl;
sdl.sdl_family = AF_LINK;
sdl.sdl_alen = ETHER_ADDR_LEN;
/* First, remove any existing filter entries. */
while(SLIST_FIRST(&sc->vlan_mc_listhead) != NULL) {
@ -138,7 +140,7 @@ vlan_setmulti(struct ifnet *ifp)
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT);
mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_WAITOK);
bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
(char *)&mc->mc_addr, ETHER_ADDR_LEN);
SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries);
@ -226,6 +228,17 @@ vlan_start(struct ifnet *ifp)
if (ifp->if_bpf)
bpf_mtap(ifp, m);
/*
* Do not run parent's if_start() if the parent is not up,
* or parent's driver will cause a system crash.
*/
if ((p->if_flags & (IFF_UP | IFF_RUNNING)) !=
(IFF_UP | IFF_RUNNING)) {
m_freem(m);
ifp->if_data.ifi_collisions++;
continue;
}
/*
* If the LINK0 flag is set, it means the underlying interface
* can do VLAN tag insertion itself and doesn't require us to
@ -376,9 +389,11 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
ifv->ifv_if.if_mtu = p->if_data.ifi_mtu - EVL_ENCAPLEN;
/*
* Preserve the state of the LINK0 flag for ourselves.
* Copy only a selected subset of flags from the parent.
* Other flags are none of our business.
*/
ifv->ifv_if.if_flags = (p->if_flags & ~(IFF_LINK0));
ifv->ifv_if.if_flags = (p->if_flags &
(IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | IFF_POINTOPOINT));
/*
* Set up our ``Ethernet address'' to reflect the underlying
@ -502,8 +517,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
if (vlr.vlr_parent[0] == '\0') {
vlan_unconfig(ifp);
if_down(ifp);
ifp->if_flags &= ~(IFF_UP|IFF_RUNNING);
if (ifp->if_flags & IFF_UP) {
int s = splimp();
if_down(ifp);
splx(s);
}
ifp->if_flags &= ~IFF_RUNNING;
break;
}
p = ifunit(vlr.vlr_parent);