mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
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:
parent
9112dc499f
commit
249932144b
1 changed files with 25 additions and 6 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue